Skip to content

Commit 4fd2d70

Browse files
committed
split up cutflow, change NN->BDT in histogram name, clean up iso/quality cut logic
1 parent 16f529d commit 4fd2d70

6 files changed

+151
-168
lines changed

src/WWZ_ana.jl

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function WWZ_chi2(Z_pair, W_pair, v_l_pid, v_l_tlv)
2626
end
2727

2828
function WWZ_Cut(
29-
Z_pair, W_pair, v_l_pid, v_l_order, v_l_tlv
29+
Z_pair, W_pair, v_l_pid, v_l_order, v_l_tlv, dict, cutflow_ptr, NN_hist
3030
)
3131
chi2 = WWZ_chi2(Z_pair, W_pair, v_l_pid, v_l_tlv)
3232
FAIL = (false, Inf, W_pair)
@@ -37,10 +37,15 @@ function WWZ_Cut(
3737
WWZ_dilepton_mass < 12 && return FAIL
3838
end
3939
end
40+
cutflow_ptr[] += 1
41+
if NN_hist push!(dict[:CutFlow], cutflow_ptr[]) end
42+
4043
@inbounds pt(v_l_tlv[v_l_order[1]]) < 30 && return FAIL
4144
@inbounds pt(v_l_tlv[v_l_order[2]]) < 15 && return FAIL
4245
@inbounds pt(v_l_tlv[v_l_order[3]]) < 8 && return FAIL
4346
@inbounds pt(v_l_tlv[v_l_order[4]]) < 6 && return FAIL
47+
cutflow_ptr[] += 1
48+
if NN_hist push!(dict[:CutFlow], cutflow_ptr[]) end
4449

4550
# selected lepton min dR
4651
@inbounds for i in 1:4
@@ -49,7 +54,8 @@ function WWZ_Cut(
4954
dR < 0.1 && return FAIL
5055
end
5156
end
52-
57+
cutflow_ptr[] += 1
58+
if NN_hist push!(dict[:CutFlow], cutflow_ptr[]) end
5359

5460
return true, chi2, W_pair
5561
end

src/analysis_utils.jl

+13-13
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ const ANALYSIS_DIR = Ref("/data/jiling/WVZ/v2.3_hists")
88
const ONNX_MODEL_PATH = Ref("/data/grabanal/NN/NN_08_23.onnx")
99
const BDT_MODEL_PATH = Ref("/home/rjacobse/BDT/kfolding/")
1010

11-
function init_ONNX()
12-
model=ONNX.load(ONNX_MODEL_PATH[], zeros(Float32, 30, 1))
13-
rescaling_parameters = joinpath(dirname(@__DIR__), "config/NN_08_23_rescaling_parameters.json") |> read |> JSON3.read
14-
NN_order = ("HT", "MET", "METPhi", "METSig", "Njet", "Wlep1_dphi", "Wlep1_eta",
15-
"Wlep1_phi", "Wlep1_pt", "Wlep2_dphi", "Wlep2_eta", "Wlep2_phi",
16-
"Wlep2_pt", "Zcand_mass", "Zlep1_dphi", "Zlep1_eta", "Zlep1_phi",
17-
"Zlep1_pt", "Zlep2_dphi", "Zlep2_eta", "Zlep2_phi", "Zlep2_pt",
18-
"leptonic_HT", "mass_4l", "other_mass", "pt_4l", "total_HT",
19-
"sr_SF_inZ", "sr_SF_noZ", "sr_DF")
20-
return model,
21-
[rescaling_parameters["scale"][name] for name in NN_order],
22-
[rescaling_parameters["min"][name] for name in NN_order]
23-
end
11+
function init_ONNX()
12+
model=ONNX.load(ONNX_MODEL_PATH[], zeros(Float32, 30, 1))
13+
rescaling_parameters = joinpath(dirname(@__DIR__), "config/NN_08_23_rescaling_parameters.json") |> read |> JSON3.read
14+
NN_order = ("HT", "MET", "METPhi", "METSig", "Njet", "Wlep1_dphi", "Wlep1_eta",
15+
"Wlep1_phi", "Wlep1_pt", "Wlep2_dphi", "Wlep2_eta", "Wlep2_phi",
16+
"Wlep2_pt", "Zcand_mass", "Zlep1_dphi", "Zlep1_eta", "Zlep1_phi",
17+
"Zlep1_pt", "Zlep2_dphi", "Zlep2_eta", "Zlep2_phi", "Zlep2_pt",
18+
"leptonic_HT", "mass_4l", "other_mass", "pt_4l", "total_HT",
19+
"sr_SF_inZ", "sr_SF_noZ", "sr_DF")
20+
return model,
21+
[rescaling_parameters["scale"][name] for name in NN_order],
22+
[rescaling_parameters["min"][name] for name in NN_order]
23+
end
2424

2525
function init_BDT()
2626
SFinZs = Tuple(

src/constants.jl

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1+
const CUTFLOW_NAMES = [
2+
:in_minitree,
3+
:pass_trigger,
4+
:fourl_with_eta_mask,
5+
:has_Z_candidate,
6+
:pass_lepton_quality,
7+
:pass_lepton_iso,
8+
:SFOS_m_12GeVplus,
9+
:lepton_minimum_pts,
10+
:dilepton_dR_0p1plus,
11+
:no_Bjet,
12+
:MET_10GeVplus
13+
]
114
const SIG_TAGS = ("Signal", )
215
const BKG_TAGS = ("ZZ", "Zjets", "Zgamma", "ttbar", "WZ", "tZ", "ttZ", "tWZ", "VBS", "VH", "Others")
3-
const ALL_TAGS = (SIG_TAGS..., BKG_TAGS...)
16+
const ALL_TAGS = [SIG_TAGS...; BKG_TAGS...]
417
const Z_m = 91.1876 # everything in GeV
518
const e_mass = 0.51099885 / 1000
619
const m_mass = 105.65837 / 1000

src/hist_exfiltration.jl

+17-39
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,31 @@
1-
function NN_hist_init(; sfsys, shape_variation)
2-
if sfsys && (shape_variation != "NOMINAL")
3-
error("can't do sf systematics and shape systematics at the same time")
4-
end
5-
_dict = Dict{Symbol, Hist1D}()
6-
bins = 0:0.01:1
7-
for n in (:SFinZ__NN, :SFnoZ__NN, :DF__NN)
8-
_dict[Symbol(n, :__, shape_variation)] = Hist1D(Float64; bins, overflow=true)
9-
1+
function populate_hist!(dict, shape_variation, symbols, bins, sfsys)
2+
for n in symbols
3+
dict[Symbol(n, :__, shape_variation)] = Hist1D(Float64; bins, overflow=true)
104
!sfsys && continue
115
for (_,vs) in SF_BRANCH_DICT
126
for v in vs
13-
_dict[Symbol(n, :__, v)] = Hist1D(Float64; bins, overflow=true)
7+
dict[Symbol(n, :__, v)] = Hist1D(Float64; bins, overflow=true)
148
end
159
end
1610
end
17-
bins = 0:5:300
18-
for n in (:SFinZ__MET, :SFnoZ__MET, :DF__MET)
19-
_dict[Symbol(n, :__, shape_variation)] = Hist1D(Float64; bins, overflow=true)
11+
end
2012

21-
!sfsys && continue
22-
for (_,vs) in SF_BRANCH_DICT
23-
for v in vs
24-
_dict[Symbol(n, :__, v)] = Hist1D(Float64; bins, overflow=true)
25-
end
26-
end
13+
function NN_hist_init(; sfsys, shape_variation)
14+
if sfsys && (shape_variation != "NOMINAL")
15+
error("can't do sf systematics and shape systematics at the same time")
2716
end
28-
bins = 0:5
29-
for n in (:SFinZ__Njet, :SFnoZ__Njet, :DF__Njet)
30-
_dict[Symbol(n, :__, shape_variation)] = Hist1D(Float64; bins, overflow=true)
17+
_dict = Dict{Symbol, Hist1D}()
3118

32-
!sfsys && continue
33-
for (_,vs) in SF_BRANCH_DICT
34-
for v in vs
35-
_dict[Symbol(n, :__, v)] = Hist1D(Float64; bins, overflow=true)
36-
end
37-
end
38-
end
39-
for n in (:ZZCR__Njet, :ttZCR__Njet)
40-
_dict[Symbol(n, :__, shape_variation)] = Hist1D(Float64; bins, overflow=true)
19+
bins = 0:0.01:1
20+
populate_hist!(_dict, shape_variation, (:SFinZ__BDT, :SFnoZ__BDT, :DF__BDT), bins, sfsys)
4121

42-
!sfsys && continue
43-
for (_,vs) in SF_BRANCH_DICT
44-
for v in vs
45-
_dict[Symbol(n, :__, v)] = Hist1D(Float64; bins, overflow=true)
46-
end
47-
end
48-
end
22+
bins = 0:5:300
23+
populate_hist!(_dict, shape_variation, (:SFinZ__MET, :SFnoZ__MET, :DF__MET), bins, sfsys)
24+
25+
bins = 0:5
26+
populate_hist!(_dict, shape_variation, (:SFinZ__Njet, :SFnoZ__Njet, :DF__Njet, :ZZCR__Njet, :ttZCR__Njet), bins, sfsys)
4927

50-
_dict[:CutFlow] = Hist1D(Int; bins=0:20)
28+
_dict[:CutFlow] = Hist1D(Int; bins=1:20)
5129

5230
return _dict
5331
end

src/mainlooper.jl

+54-55
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,22 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
3838
model = models # for BDT
3939
for evt in mytree
4040
### initial_cut
41-
cutflow_ptr = 0
42-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
41+
cutflow_ptr = Ref(1)
42+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
43+
44+
!(evt.passTrig) && continue
45+
cutflow_ptr[] += 1
46+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
47+
4348
v_m_eta_orig, v_e_caloeta_orig = evt.v_m_eta, evt.v_e_caloeta
4449
e_etamask = [abs(η) < 2.47 && (abs(η)<1.37 || abs(η)>1.52) for η in v_e_caloeta_orig]
4550
m_etamask = [abs(η) < 2.5 for η in v_m_eta_orig]
4651
v_l_pid = @views Vcat(evt.v_e_pid[e_etamask], evt.v_m_pid[m_etamask])
47-
4852
Nlep = length(v_l_pid)
4953
Nlep != 4 && continue
50-
cutflow_ptr += 1
51-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
54+
cutflow_ptr[] += 1
55+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
56+
5257
Nelec = count(e_etamask)
5358
Nmuon = Nlep - Nelec
5459
(; v_e_pt, v_e_eta, v_e_phi,
@@ -61,65 +66,61 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
6166
v_e_tlv = @views LorentzVectorCyl.(v_e_pt[e_etamask], v_e_eta[e_etamask], v_e_phi[e_etamask], v_e_m[e_etamask])
6267
v_m_tlv = @views LorentzVectorCyl.(v_m_pt[m_etamask], v_m_eta[m_etamask], v_m_phi[m_etamask], v_m_m[m_etamask])
6368
v_l_tlv = Vcat(v_e_tlv, v_m_tlv)
69+
6470
Z_pair, W_pair, best_Z_mass = Find_Z_Pairs(v_l_pid, v_l_tlv)
6571
isinf(best_Z_mass) && continue
66-
cutflow_ptr += 1
67-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
6872
other_mass = mass(v_l_tlv[W_pair[1]] + v_l_tlv[W_pair[2]])
6973
abs(best_Z_mass - Z_m) > 20 && continue
70-
cutflow_ptr += 1
71-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
74+
cutflow_ptr[] += 1
75+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
76+
7277
mass_4l = mass(sum(v_l_tlv))
7378
mass_4l < 0.0 && continue
74-
cutflow_ptr += 1
75-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
7679
### end of initial_cut
77-
!(evt.passTrig) && continue
78-
cutflow_ptr += 1
79-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
80+
8081
v_l_order = sortperm(v_l_tlv; by=pt, rev=true)
81-
v_l_medium = @views Vcat(evt.v_e_LHMedium[e_etamask] , evt.v_m_medium[m_etamask]) #quality
8282

83-
############## use PLIV for W lepton ISO #################
84-
v_l_PLTight = Vcat(evt.v_e_passIso_PLImprovedTight[e_etamask], evt.v_m_passIso_PLImprovedTight[m_etamask])
85-
# if controlregion == :Zjets
86-
# failed_PLTight = any(==(true), v_l_PLTight[W_pair])
87-
# failed_PLTight && continue
88-
# v_l_Loose = Vcat(evt.v_e_passIso_Loose_VarRad, evt.v_m_passIso_PflowLoose_VarRad)
89-
# failed_Loose = all(==(true), v_l_Loose[W_pair])
90-
# failed_Loose && continue
91-
# else
92-
failed_PLTight = any(==(false), v_l_PLTight[W_pair])
93-
failed_PLTight && continue
94-
cutflow_ptr += 1
95-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
96-
# end
97-
(;
98-
v_e_passIso_Loose_VarRad,
99-
v_m_passIso_PflowLoose_VarRad,
100-
) = evt
83+
### QUALITY
84+
v_l_medium = @views Vcat(evt.v_e_LHMedium[e_etamask] , evt.v_m_medium[m_etamask])
85+
# for W leptons, require medium quality
86+
!v_l_medium[W_pair[1]] && continue
87+
!v_l_medium[W_pair[2]] && continue
88+
# for Z leptons only Loose requirement, no additional quality cut
89+
#
90+
cutflow_ptr[] += 1
91+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
92+
93+
### ISOLATION
94+
# for W leptons, require PLIVTight Isolation
95+
v_l_PLTight = @views Vcat(evt.v_e_passIso_PLImprovedTight[e_etamask], evt.v_m_passIso_PLImprovedTight[m_etamask])
96+
!v_l_PLTight[W_pair[1]] && continue
97+
!v_l_PLTight[W_pair[2]] && continue
98+
# for Z leptons require Loose isolation
99+
(;v_e_passIso_Loose_VarRad, v_m_passIso_PflowLoose_VarRad) = evt
101100
v_l_passIso = @views Vcat(v_e_passIso_Loose_VarRad[e_etamask], v_m_passIso_PflowLoose_VarRad[m_etamask])
101+
!v_l_passIso[Z_pair[1]] && continue
102+
!v_l_passIso[Z_pair[2]] && continue
103+
104+
cutflow_ptr[] += 1
105+
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
106+
102107

103108
pass_WWZ_cut, chisq, W_id = WWZ_Cut(
104109
Z_pair,
105110
W_pair,
106111
v_l_pid,
107112
v_l_order,
108-
v_l_tlv
113+
v_l_tlv,
114+
dict,
115+
cutflow_ptr,
116+
NN_hist
109117
)
110-
for i in 1:2
111-
### for Z leptons isolation: Loose(e) and Loose(mu)
112-
!v_l_passIso[Z_pair[i]] && (pass_WWZ_cut = false)
113-
114-
### for W leptons, require medium quality and PLIV tight
115-
!v_l_medium[W_pair[i]] && (pass_WWZ_cut = false)
116-
end
117118

118119
!pass_WWZ_cut && continue
119-
cutflow_ptr += 1
120-
if NN_hist pusher!(dict[:CutFlow], cutflow_ptr) end
121120

122121
has_b = any(evt.v_j_btag77)
122+
cutflow_ptr[] += 1
123+
if !has_b && NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
123124

124125
(; MET, METSig, METPhi) = evt
125126
MET /= 1000
@@ -133,7 +134,7 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
133134
make_sfsys_wgt!(evt, wgt_dict,
134135
:weight; sfsys, pre_mask=1)
135136
make_sfsys_wgt!(evt, wgt_dict,
136-
:v_j_wgt_btag77, : ; sfsys)
137+
:v_j_wgt_btag77, Colon() ; sfsys)
137138
# I hate indexing
138139
Z_pair_in_e = filter(<=(Nelec), Z_pair)
139140
Z_pair_in_m = filter!(>(0), Z_pair .- Nelec)
@@ -162,14 +163,12 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
162163
make_sfsys_wgt!(evt, wgt_dict,
163164
:v_m_wgtIso_PflowLoose_VarRad,
164165
Z_pair_in_m; pre_mask = m_etamask, sfsys)
165-
# if controlregion != :ZJets
166-
make_sfsys_wgt!(evt, wgt_dict,
167-
:v_e_wgtIso_PLImprovedTight_Medium,
168-
W_pair_in_e; pre_mask = e_etamask, sfsys)
169-
make_sfsys_wgt!(evt, wgt_dict,
170-
:v_m_wgtIso_PLImprovedTight,
171-
W_pair_in_m; pre_mask = m_etamask, sfsys)
172-
# end
166+
make_sfsys_wgt!(evt, wgt_dict,
167+
:v_e_wgtIso_PLImprovedTight_Medium,
168+
W_pair_in_e; pre_mask = e_etamask, sfsys)
169+
make_sfsys_wgt!(evt, wgt_dict,
170+
:v_m_wgtIso_PLImprovedTight,
171+
W_pair_in_m; pre_mask = m_etamask, sfsys)
173172
end
174173

175174
lep1_pid, lep2_pid, lep3_pid, lep4_pid = @view v_l_pid[v_l_order]
@@ -238,6 +237,8 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
238237
if cr_ZZ || cr_ttZ
239238
SR = -1
240239
end
240+
cutflow_ptr[] += 1
241+
if MET>10 && NN_hist pusher!(dict[:CutFlow], cutflow_ptr[]) end
241242

242243
if NN_hist && !arrow_making
243244
region_prefix = if sr_SF_inZ
@@ -256,9 +257,7 @@ function main_looper(mytree, sumWeight, dict, pusher!, models,
256257
elseif cr_ttZ
257258
pusher!(dict[Symbol(:ttZCR, :__Njet, :__, k)], Njet, v)
258259
elseif SR >= 0
259-
cutflow_ptr += 1
260-
pusher!(dict[:CutFlow], cutflow_ptr)
261-
pusher!(dict[Symbol(region_prefix, :__NN, :__, k)], NN_score, v)
260+
pusher!(dict[Symbol(region_prefix, :__BDT, :__, k)], NN_score, v)
262261
pusher!(dict[Symbol(region_prefix, :__MET, :__, k)], MET, v)
263262
pusher!(dict[Symbol(region_prefix, :__Njet, :__, k)], Njet, v)
264263
end

0 commit comments

Comments
 (0)