Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
231a5f8
Basic photon selection
bryates Apr 13, 2023
94ba9ca
Saving single photon pT
bryates Apr 20, 2023
3a74343
edited photon selection category to include kinematic cuts
abasnet97 Jun 8, 2023
fb442bb
edited 2los CR category
abasnet97 Jun 8, 2023
f704e98
modified photon selection furthermore
abasnet97 Jun 12, 2023
58d2662
Merge all recent master changes to photon branch
abasnet97 Jun 12, 2023
0837563
changed photon ID from tight to medium for now
abasnet97 Jun 12, 2023
c594dfe
More flake8 fixes
kmohrman Mar 25, 2023
2ec1020
More flake8 fixes..
kmohrman Mar 26, 2023
439e92f
Basic photon selection
bryates Apr 13, 2023
d0748bc
Saving single photon pT
bryates Apr 20, 2023
58c9f63
Adding ttgamma selection
bryates Jun 15, 2023
cc6fcc9
more photon selection edits
abasnet97 Jun 21, 2023
2f5cc8c
Add cutBased hist, medium photon ID
bryates Jun 21, 2023
ff5b88c
Merge branch 'photons' of github.com:TopEFT/topcoffea into photons
bryates Jun 21, 2023
ed17052
Relaxed veto
bryates Jun 22, 2023
44b5fe1
Fixed typo
bryates Jun 22, 2023
7f55206
editing the processor to include relaxed cutBasedID for photon
abasnet97 Jun 29, 2023
18f210d
fixing typo in selection.py
abasnet97 Jun 29, 2023
cb0a510
Working version
bryates Jun 30, 2023
9511813
fix masks
bryates Jun 30, 2023
1855fb3
merged changes from master after topcoffea refactoring
abasnet97 Sep 18, 2023
e38731b
added new files related to photon gen processor
abasnet97 Oct 19, 2023
4c02a90
new edits to gen level processor
abasnet97 Dec 11, 2023
178aec4
modify genlepflav mask
abasnet97 Dec 11, 2023
573ae6c
several modifications to photon object and event selections
abasnet97 Feb 27, 2024
eda50d7
implemented ttgamma ttbar overlap removal
abasnet97 Mar 12, 2024
f80b263
added genParentage
abasnet97 Mar 12, 2024
0117164
major changes to overlap removal implementation and other cleanups
abasnet97 Apr 15, 2024
54085ea
added a helper script to make njet-nbjet histogram
abasnet97 May 2, 2024
d754dec
added a helper function to make jet_bjet plot
abasnet97 Jun 20, 2024
7c7e73d
updated processor file to include new control regions for ttgamma work
abasnet97 Jun 20, 2024
3911341
updated event and object selection to include CR selections for ttgam…
abasnet97 Jun 20, 2024
19d051e
removing ttgamma and Zgamma from conversion samples list
abasnet97 Jun 20, 2024
98f5df9
Adding photon SFs and systematic
bryates Jun 21, 2024
e2ced76
Use `photonSFs` branch of topcoffea
bryates Jun 21, 2024
7a705e6
Fix some lint issues
bryates Jun 21, 2024
5a17f4d
Remove stray print
bryates Jun 21, 2024
e9c4c78
Removing unused masks
bryates Jun 24, 2024
285aef2
TTGamma is now a signal process, TTG->ttA
bryates Jun 28, 2024
bf52a61
Pull latest datacard maker, update categories
bryates Jun 28, 2024
98bfa02
Zero our missing sumw2
bryates Jun 28, 2024
86113a4
Merge branch 'master' into photons_rebase
bryates Jul 1, 2024
4003f38
Fix lint, move gen processor to histEFT
bryates Jul 1, 2024
d5a61ea
More lint
bryates Jul 1, 2024
1b18c4b
Yet more lint
bryates Jul 1, 2024
2485b1a
Fix typos
bryates Jul 1, 2024
695e231
Lint again!
bryates Jul 1, 2024
501a834
Never-ending lint
bryates Jul 1, 2024
22ef77b
Add `ttA` to processes
bryates Jul 1, 2024
77a8ea7
Processor runs now
bryates Jul 1, 2024
1f2a507
Merge branch 'photons_histEFT' into photon_dc
bryates Jul 1, 2024
fb66108
Use new `EGamma_SF2D_err` hists
bryates Jul 2, 2024
047aad7
Load photon SFs, still load lepton SFs in those channels
bryates Jul 2, 2024
c33e8c6
Simplify 2l category
bryates Jul 2, 2024
ccae998
Back to main TopCoffea branch
bryates Jul 2, 2024
ba4b98f
Fix some comment typos
bryates Jul 3, 2024
5aa2036
Fix typo in 2l
bryates Jul 3, 2024
780e38c
Back to main TopCoffea branch
bryates Jul 3, 2024
380d4f3
Replace prune with slice
bryates Jul 10, 2024
da40fc5
Fixed CI yields, removed (hopefully) unneeded code
bryates Jul 10, 2024
b85714b
Merge branch 'photons_histEFT' into photon_dc
bryates Jul 11, 2024
b5aa458
Update photon SR
bryates Jul 16, 2024
c42728c
Clean up run script
bryates Jul 16, 2024
fb4a267
Better 2l cats
bryates Jul 18, 2024
6015877
Switch to medium SFs
bryates Jul 29, 2024
018157b
Restored missing overlap functions
bryates Jul 30, 2024
519ff51
Checkout `photon_seedveto` on TopCoffea
bryates Jul 30, 2024
8491d25
Fix lint
bryates Jul 30, 2024
ef20b9a
Working pxiel seed veto and CSEV
bryates Jul 30, 2024
b826e72
Fix lint space at end
bryates Jul 30, 2024
beafecf
Fix lint indents
bryates Jul 30, 2024
31225ac
Merge branch 'master' into photons_histEFT
bryates Jul 30, 2024
1832dfa
Add photon categories
bryates Aug 14, 2024
24536db
Added ttgamma categories to ref json
bryates Aug 14, 2024
84edb0b
Update main.yml
bryates Sep 5, 2024
ee7a0db
Fix typo in photon error propagation
bryates Sep 5, 2024
84c2cb0
Yields after applying new photon vetoes (pixel and CSEV)
bryates Sep 5, 2024
72e0e0e
Yields after TopCoffea correction-lib updates
bryates Sep 5, 2024
30b3af4
Merge branch 'master' into photons_histEFT_rebase
bryates Nov 18, 2024
4c77311
Small changes for photon channels
bryates Nov 19, 2024
7415ccb
Merge branch 'photons_histEFT' into photon_dc
bryates Nov 19, 2024
9ae1951
Merge branch 'photons_histEFT' into photon_dc
bryates Nov 19, 2024
fb6238d
"Fix" for 2los photon channels
bryates Nov 21, 2024
30eacf4
Add `TTGamma_private`
bryates Nov 22, 2024
14ceef4
Skip `renormfact` since we never used it
bryates Nov 25, 2024
bca3988
Merge branch 'master' into photons_histEFT
bryates Dec 4, 2024
b1e716a
adding a new plotting helper script. will add the changes to analysis…
abasnet97 Jan 22, 2025
adabbab
lint fix
abasnet97 Jan 22, 2025
c2089dc
Some TTGamma files missing
bryates Jan 23, 2025
fc9e8f2
Merge branch 'photons_histEFT' into photon_dc
bryates Jan 23, 2025
2d64ee8
Latest IM changes
bryates Jan 23, 2025
61b479f
wc ranges from master
bryates Jan 23, 2025
febd140
Fixed ttA typo
bryates Jan 23, 2025
ce27be4
added new histograms relevant to non-prompt photon estimation
abasnet97 Jan 26, 2025
4d17ed9
Merge branch 'photons_histEFT' of https://github.com/TopEFT/topeft in…
abasnet97 Jan 26, 2025
0efd8cb
adding prompt subtraction samples for photons
abasnet97 Jan 26, 2025
90157cf
a new helper function to aid histogram filling
abasnet97 Jan 26, 2025
03c0e8f
updated corrections, event and object selection scripts to handle non…
abasnet97 Jan 26, 2025
56448ea
adding numpy files for photon FR and kMC
abasnet97 Jan 26, 2025
a625eff
lint fixes
abasnet97 Jan 26, 2025
90d52da
more lint fixes cause why not
abasnet97 Jan 26, 2025
e524a53
temporarily comment out photon_pt_eta hist
abasnet97 Jan 28, 2025
d1294ea
massive overhaul of photon selection and analysis channels
abasnet97 Jan 28, 2025
8e16511
clean the processor and add nonprompt fakerate as event weight
abasnet97 Jan 28, 2025
630d4a2
added photon fakerate and kMC numpy files
abasnet97 Jan 30, 2025
b1ec71d
adding ISR/FSR split of photons in ZGamma sample
abasnet97 Jan 30, 2025
07b0530
fix lint
abasnet97 Jan 30, 2025
ddad937
bringing photon_pt_eta histogram back
abasnet97 Jan 31, 2025
8d481f8
added modifications to perform nonprompt estimation of photons
abasnet97 Jan 31, 2025
56cb888
lint fixes
abasnet97 Jan 31, 2025
f866b86
possible attempt at fixing CI
abasnet97 Jan 31, 2025
b04ddb3
new photon FRs and kMC factors after including EFT signal samples
abasnet97 Feb 10, 2025
117c382
editing processor to handle eft weights for 2D histogram
abasnet97 Feb 11, 2025
eb6520a
further edits to the nonprompt mc stat uncertainty propagation
abasnet97 Feb 12, 2025
5e0ea7c
lint fixes
abasnet97 Feb 12, 2025
3ec217e
Merge pull request #420 from TopEFT/photon_dc
abasnet97 Feb 12, 2025
fb42fc1
adding EFT sig samples in prompt photon subtraction list
abasnet97 Feb 12, 2025
135f3a0
Merge branch 'photons_histEFT' of https://github.com/TopEFT/topeft in…
abasnet97 Feb 12, 2025
1f5554d
modifications to datacard_tools for photon channels
abasnet97 Feb 12, 2025
51e2829
Merging master
bryates Feb 14, 2025
258fab5
Missing calls
bryates Feb 14, 2025
81a4e4d
Merge branch 'master' into photons_histEFT_master2
bryates Feb 14, 2025
4f93da2
Indent
bryates Feb 14, 2025
3c9f638
Turn off debug messages
bryates Feb 14, 2025
8f3a250
Photon systs only when flag is set
bryates Feb 14, 2025
4006c45
Fix typo
bryates Feb 14, 2025
9caecd2
Should all work
bryates Feb 14, 2025
60213b9
Photon channels
bryates Feb 14, 2025
3882dd4
Fixed processor
bryates Feb 14, 2025
6424d8b
Removed comment
bryates Feb 14, 2025
641247e
Lint
bryates Feb 14, 2025
80d5187
Undo change
bryates Feb 14, 2025
9c78263
Remove 2los_ph from cat lst
bryates Feb 14, 2025
7c116b3
Fix CR name
bryates Mar 3, 2025
3276a6e
Add 0m b mask for CR
bryates Mar 3, 2025
d4c27ce
Add sf and of
bryates Mar 3, 2025
83eb2e2
More channel updates
bryates Mar 4, 2025
a23f37e
Fixed flavor channels
bryates Mar 5, 2025
f9faf23
modified appl axes names and channel list json
abasnet97 Mar 5, 2025
6658b39
some minor modifications to datacard tools
abasnet97 Mar 5, 2025
2991ffe
adding ST TWG sample to non prompt photon subtraction list
abasnet97 Mar 5, 2025
4696058
adding 1jet diboson uncertainty (temporary fix to make ttA datacards)
abasnet97 Mar 5, 2025
c89284a
lint fixes
abasnet97 Mar 5, 2025
f37da9b
adding jsons for UL17 and UL16APV ttgamma EFT samples and modifying c…
abasnet97 Mar 5, 2025
369552b
adding photon mask on ch_lst_test json
abasnet97 Mar 7, 2025
7724993
including photon relevant code block inside the ttA_analysis flag
abasnet97 Mar 12, 2025
444baaa
bit more restructuring of the analysis processor
abasnet97 Mar 12, 2025
828e76e
remove photon_pt_eta 2D hist once they serve their purpose
abasnet97 Mar 13, 2025
be8bb08
lint fixes
abasnet97 Mar 13, 2025
7018870
added nEvents and nGenEvents info to ttgamma jsons
abasnet97 Mar 16, 2025
914c216
added new jsons and cfg file for TWGToLL samples
abasnet97 Mar 31, 2025
5ca5a3a
edited ttgamma channels in channel list json
abasnet97 Apr 30, 2025
e200e74
modified corrections module to add correction factor for private ttga…
abasnet97 Apr 30, 2025
1afe914
update new photon FR and kMC npz files and ttgamma correction factor …
abasnet97 Apr 30, 2025
f14b8e7
remove hardcoded bin edges
abasnet97 May 1, 2025
b0af705
minor edits to params and rate_systs json files
abasnet97 May 1, 2025
043a5f9
several changes to analysis processor to include private ttgamma corr…
abasnet97 May 1, 2025
4a9d8f0
changing some aspects of nonprompt photon estimation and modification…
abasnet97 May 1, 2025
c67a3d0
lint fixes
abasnet97 May 1, 2025
9cfa06c
appeased the lint god
abasnet97 May 1, 2025
3b98556
cleaning overlap removal block
abasnet97 May 1, 2025
fd72623
modifying some photon kinematic variables binning
abasnet97 May 5, 2025
afb8941
changing some kinematic variable binning
abasnet97 May 5, 2025
57e573d
modified private ttA CF block to handle systematic uncertainty
abasnet97 May 5, 2025
b325ab1
few more changes on non prompt photon estimation block
abasnet97 May 5, 2025
bef0b0c
modifying photon fakerates and kmc factors paths
abasnet97 May 5, 2025
addb7d7
use validation test instead of closure test
abasnet97 May 5, 2025
2b15f21
minor edits to kinematic binnings
abasnet97 May 5, 2025
b410979
changing some kinematic variable binning
abasnet97 May 5, 2025
476ccf6
modified private ttA CF block to handle systematic uncertainty
abasnet97 May 5, 2025
955b7ec
few more changes on non prompt photon estimation block
abasnet97 May 5, 2025
a834944
modifying photon fakerates and kmc factors paths
abasnet97 May 5, 2025
81a12d4
use validation test instead of closure test
abasnet97 May 5, 2025
81ca2ef
minor edits to kinematic binnings
abasnet97 May 5, 2025
216b478
Merge branch 'photons_histEFT' of github.com:TopEFT/topeft into photo…
abasnet97 May 5, 2025
2271e93
removed harcoded kinematic cuts
abasnet97 May 6, 2025
8f4ab95
adding pdf and qcd scale uncertainties on ttg NLO xsec
abasnet97 May 6, 2025
2fe2ac0
fix a typo
abasnet97 May 6, 2025
53d6f70
modify nonprompt photon syst unc on last photon pt bin
abasnet97 May 6, 2025
ce395d2
delete redundant fakerate files
abasnet97 May 6, 2025
1da4d6d
adding new syst. uncertainties relevant to ttA analyses
abasnet97 Jun 6, 2025
366b58e
adding tW and tbarW samples in overlap removal list
abasnet97 Jun 6, 2025
80d778d
adding ttg correction systematic uncertainties
abasnet97 Jun 6, 2025
1f90e83
documenting photon fakerate derivation steps
abasnet97 Jun 6, 2025
e2003f8
editing the README
abasnet97 Jun 6, 2025
7b9f16c
more edits
abasnet97 Jun 6, 2025
c5731c7
new photon fakerates after fixing tW/tWgamma overlap removal
abasnet97 Jun 12, 2025
df79351
ttgamma EFT samples for Run2
abasnet97 Jun 16, 2025
6a6d669
adding data mc agreement CR back
abasnet97 Aug 4, 2025
ec1a474
missing parton root file for ttA channels
abasnet97 Aug 4, 2025
74c55e1
modifying prompt subtraction sample list
abasnet97 Aug 4, 2025
48e64d4
correct overlap removal sample list
abasnet97 Aug 4, 2025
8d7b8ca
updating nonprompt unc propagation helper instruction
abasnet97 Aug 6, 2025
877f667
adding option to pass flag to run ttA setup for datacard making
abasnet97 Aug 7, 2025
7fb1b33
update unskimmed ttg sample jsons
abasnet97 Aug 7, 2025
65f6bc5
edited setup.py to include photon fakerates, kmc, and ttg correction …
abasnet97 Aug 7, 2025
032d161
scripts to derive nonprompt photon fakerates and kmc factors
abasnet97 Aug 8, 2025
f236d0e
lint fixes
abasnet97 Aug 8, 2025
7e189c3
more lint fixes
abasnet97 Aug 8, 2025
8d2e5d4
why cant lint fix itself?
abasnet97 Aug 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions analysis/photon_fakerate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
### Setting up
The setups are exactly the same as the one for running the main analysis processor.

### What do each of the scripts do?
- `derive_nonprompt_fakerate.py`: This script is used to derive the nonprompt photon fakerate (FR). The same FR is good for the ABCD and LRCD (validation) regions. The FR derivation takes all the data and MC samples.

- `derive_nonprompt_kmc.py`: This script is used to derive the kMC factors for the ABCD region. The kMC derivation only requires ttbar MC samples.

- `derive_nonprompt_kmc_LRCD.py`: This script is used to derive the kMC factors for the LRCD validation region. The kMC validation only requires ttbar MC samples.

### Important notes
- Currently we do not include systematic uncertainties when derive the fake rates and kMC factors.

### Commands:

1. Nonprompt fakerate derivation:
```
time python run_derive_nonprompt_fakerate.py <data_cfg>,<mc_cfg> --hist-list nonprompt -s 50000 -o <output_pkl_file_name>
```

2. kMC derivation:
```
time python run_derive_nonprompt_kmc.py <ttbar_mc_cfg> --hist-list nonprompt -s 50000 -o <output_pkl_file_name>
```

3. kMC validation derivation:
```
time python run_derive_nonprompt_kmc_LRCD.py <ttbar_mc_cfg> --hist-list nonprompt -s 50000 -o <output_pkl_file_name>
```

### Extracting FR and kMC
Once the pkl files are ready, one can use `calculate_FR.py`, `calculate_kMC.py`, and `calculate_kMC_LRDC.py` scripts to extract the fake rates and save them as numpy (.npz) files. Once these files are ready, they should be saved inside `topeft/data/photon_fakerates/` or `topeft/data/photon_kmc/` or `topeft/data/photon_kmc_validation` dirs.

### Running non-prompt validation test
TODO: add instructions
843 changes: 843 additions & 0 deletions analysis/photon_fakerate/derive_nonprompt_fakerate.py

Large diffs are not rendered by default.

839 changes: 839 additions & 0 deletions analysis/photon_fakerate/derive_nonprompt_kmc.py

Large diffs are not rendered by default.

828 changes: 828 additions & 0 deletions analysis/photon_fakerate/derive_nonprompt_kmc_LRCD.py

Large diffs are not rendered by default.

373 changes: 293 additions & 80 deletions analysis/topeft_run2/analysis_processor.py

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions analysis/topeft_run2/datacards_post_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def main():
parser.add_argument("-z", "--set-up-offZdivision", action="store_true", help = "Copy the ptz and lj0pt cards with 3l offZ division.")
parser.add_argument("-t", "--tau-flag", action="store_true", help = "Copy the ptz, lj0pt, and ptz_wtau cards for tau channels.")
parser.add_argument("-f", "--fwd-flag", action="store_true", help = "Copy the ptz, lj0pt, and lt cards for forward channels.")
parser.add_argument("-a", "--tta-flag", action="store_true", help = "Copy the ptz, lj0pt, and lt cards for forward channels.")
args = parser.parse_args()

###### Print out general info ######
Expand Down Expand Up @@ -110,6 +111,8 @@ def main():
import_sr_ch_lst = select_ch_lst["TAU_CH_LST_SR"]
if args.fwd_flag:
import_sr_ch_lst = select_ch_lst["FWD_CH_LST_SR"]
if args.tta_flag:
import_sr_ch_lst = select_ch_lst["TTA_CH_LST_SR"]

CATSELECTED = []

Expand All @@ -133,6 +136,8 @@ def main():
channelname = lep_ch_name + "_" + jet + "j_ptz_wtau"
elif args.fwd_flag and ("fwd" in lep_ch_name or "2lss_p" in lep_ch_name or "2lss_m" in lep_ch_name):
channelname = lep_ch_name + "_" + jet + "j_lt"
elif args.tta_flag and ("photon" in lep_ch_name or "2los_ph" in lep_ch_name):
channelname = lep_ch_name + "_" + jet + "j_photon_pt"
else:
channelname = lep_ch_name + "_" + jet + "j_lj0pt"
CATSELECTED.append(channelname)
Expand Down
19 changes: 19 additions & 0 deletions analysis/topeft_run2/fullR2_run_genphoton.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This script runs the wq run script with all of the settings appropriate for making SR histos for the full R2 analysis

# Name the output
#OUT_NAME="example_name"
OUT_NAME="12112023_genphotonstudies_2lOS_ttTo2L2Nu_ttgDilep_genPartFlavLeptons_v12"

# Build the run command for filling SR histos
#CFGS="../../input_samples/cfgs/mc_signal_samples_NDSkim.cfg,
CFGS="../../input_samples/cfgs/mc_background_samples_NDSkim.cfg" #,../../input_samples/cfgs/data_samples_NDSkim.cfg"
OPTIONS="--hist-list photon -s 50000 -x futures -o $OUT_NAME" # For analysis

# Build the run command for filling CR histos
#CFGS="../../input_samples/cfgs/mc_signal_samples_NDSkim.cfg,../../input_samples/cfgs/mc_background_samples_NDSkim.cfg,../../input_samples/cfgs/mc_background_samples_cr_NDSkim.cfg,../../input_samples/cfgs/data_samples_NDSkim.cfg"
#OPTIONS="--hist-list cr --skip-sr --do-systs --do-np --wc-list ctG -o $OUT_NAME" # For CR plots

# Run the processor over all Run2 samples
RUN_COMMAND="time python run_analysis_genPhoton.py $CFGS $OPTIONS"
printf "\nRunning the following command:\n$RUN_COMMAND\n\n"
$RUN_COMMAND
221 changes: 221 additions & 0 deletions analysis/topeft_run2/genProcessor_photon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#gen processor written for photon studies
#Created on October 6, 2023

#!/usr/bin/env python
import numpy as np
import awkward as ak
np.seterr(divide='ignore', invalid='ignore', over='ignore')
from coffea import processor

import hist
from topcoffea.modules.paths import topcoffea_path
from topcoffea.modules.histEFT import HistEFT
import topcoffea.modules.eft_helper as efth

from topeft.modules.paths import topeft_path
import topeft.modules.event_selection as te_es
import topeft.modules.object_selection as te_os

from topcoffea.modules.get_param_from_jsons import GetParam
get_tc_param = GetParam(topcoffea_path("params/params.json"))
get_te_param = GetParam(topeft_path("params/params.json"))

class AnalysisProcessor(processor.ProcessorABC):

def __init__(self, processs, wc_names_lst=[], hist_lst=None, ecut_threshold=None, do_errors=False, do_systematics=False, split_by_lepton_flavor=False, skip_signal_regions=False, skip_control_regions=False, muonSyst='nominal', dtype=np.float32):

self._processs = processs
self._wc_names_lst = wc_names_lst
self._dtype = dtype

# Create the histograms
proc_axis = hist.axis.StrCategory([], name="process", growth=True)
chan_axis = hist.axis.StrCategory([], name="channel", growth=True)
syst_axis = hist.axis.StrCategory([], name="systematic", label=r"Systematic Uncertainty", growth=True)
appl_axis = hist.axis.StrCategory([], name="appl", label=r"AR/SR", growth=True)
self._accumulator = {
"genphoton_pt" : HistEFT(proc_axis, hist.axis.Regular(10, 0, 200), label="$p_{T}$ $Gen\gamma$ (GeV)", wc_names=wc_names_lst),
"genlep_pt" : HistEFT(proc_axis, hist.axis.Regular(20, 0 ,200), label="$p_{T}$ $Gen lepton$ (GeV)", wc_names=wc_names_lst),
}

# Set the list of hists to fill
if hist_lst is None:
# If the hist list is none, assume we want to fill all hists
self._hist_lst = list(self._accumulator.keys())
else:
# Otherwise, just fill the specified subset of hists
for hist_to_include in hist_lst:
if hist_to_include not in self._accumulator.keys():
raise Exception(f"Error: Cannot specify hist \"{hist_to_include}\", it is not defined in the processor.")
self._hist_lst = hist_lst # Which hists to fill

# Set the booleans
self._do_errors = do_errors # Whether to calculate and store the w**2 coefficients

@property
def accumulator(self):
return self._accumulator

@property
def columns(self):
return self._columns

# Main function: run on a given dataset
def process(self, events):

### Dataset parameters ###
dataset = events.metadata["dataset"]

isData = self._processs[dataset]["isData"]
histAxisName = self._processs[dataset]["histAxisName"]
year = self._processs[dataset]["year"]
xsec = self._processs[dataset]["xsec"]
sow = self._processs[dataset]["nSumOfWeights"]

if isData: raise Exception("Error: This processor is not for data")

### Get gen particles collection ###
genPart = events.GenPart
genJet = events.GenJet

## reco ele and muon collection ###
ele = events.Electron
mu = events.Muon

is_final_mask = genPart.hasFlags(["fromHardProcess","isLastCopy"])

################## gen matched lepton selection #######################
#genEle_mask = np.abs(ele.matched_gen.pdgId)==11
#genEle_mask = abs(genPart.pdgId) == 11
ele_genpartFlavmask = ((ele.genPartFlav == 1) | (ele.genPartFlav == 15))
mu_genpartFlavmask = ((mu.genPartFlav == 1) | (mu.genPartFlav == 15))
#genEle = genPart[is_final_mask & genEle_mask]
#genMu_mask = np.abs(mu.matched_gen.pdgId)==13
#genMu_mask = abs(genPart.pdgId) == 13
#genMu = genPart[is_final_mask & genMu_mask]
genEle = ele[ele_genpartFlavmask]
genMu = mu[mu_genpartFlavmask]
genleps = ak.concatenate([genEle,genMu],axis=1)
genlep_pt_mask = genleps.pt > 20 #Require that the lepton pt be at least 20 GeV.
genlep_eta_mask = abs(genleps.eta)<2.4 #Require that the lepton be within 2.4 eta
genlep_pt_eta_mask = ak.fill_none(ak.pad_none((genlep_pt_mask & genlep_eta_mask),1),False)
genleps = genleps[genlep_pt_eta_mask]
genleps_ptsorted = genleps[ak.argsort(genleps.pt,axis=-1,ascending=False)]
genleps_ptsorted_padded = ak.pad_none(genleps_ptsorted, 2)
pt2515 = (ak.any(genleps_ptsorted_padded[:,0:1].pt>25,axis=1) & ak.any(genleps_ptsorted_padded[:,1:2].pt>15,axis=1)) #Require that the leading(sub-leading) lepton pT be at least 25(15)GeV.
#genleps_ptsorted_padded = genleps_ptsorted_padded[pt2515]
genl0 = genleps_ptsorted_padded[:,0]
genl1 = genleps_ptsorted_padded[:,1]

#pt2515 = (ak.any(genleps_ptsorted_padded[:,0:1].pt>25,axis=1) & ak.any(genleps_ptsorted_padded[:,1:2].pt>15,axis=1)) #Require that the leading(sub-leading) lepton pT be at least 25(15)GeV.

genleps_num_mask = ak.num(genleps_ptsorted) == 2 #Require that there are exactly 2 gen_matched leptons
#genleps_chargesum_zero = ak.fill_none(((genl0.charge + genl1.charge)==0),False) #Require that the two leptons are of opposite signs
genleps_chargesum_zero = (np.sign(genl0.pdgId) == - np.sign(genl1.pdgId))
genleps_chargesum_zero = ak.fill_none(genleps_chargesum_zero, False)
#genleps_final_mask = (genleps_num_mask & pt2515 & genleps_chargesum_zero)


invmass_ll = (genl0+genl1).mass
mll_min20 = ak.fill_none((invmass_ll > 20),False) #Require that the invariant mass of the lepton pairs be at least 20 GeV.
all_genleps_mask = (genleps_num_mask & pt2515 & genleps_chargesum_zero & mll_min20)

## gen Photon selection ##
genPh_mask = abs(genPart.pdgId) == 22
genPhoton = genPart[is_final_mask & genPh_mask]
is_clean_photon = te_os.isClean(genPhoton, genEle,drmin=0.4) & te_os.isClean(genPhoton,genMu,drmin=0.4) #photon isolation from leps
genPhoton = genPhoton[is_clean_photon]

events['genPhoton'] = genPhoton
te_es.GenPhotonSelection(events) #Require photon pt be 20 GeV and abs(eta) be 1.44
genPhoton = genPhoton[events.genPhoton_pT_eta_mask]

genphoton_num_mask = ak.num(genPhoton) == 1 #Require that there is exactly 1 photon



############### Jet object selection #####################
genJet_pT_eta_mask = ((genJet.pt > 30) & (abs(genJet.eta) < 2.44))
genJet_pT_eta_mask = ak.fill_none(ak.pad_none(genJet_pT_eta_mask,1),False)
genjet = genJet[genJet_pT_eta_mask] #Require that the jet pt be at least 30 GeV.
is_clean_jet = te_os.isClean(genjet, genEle, drmin=0.4) & te_os.isClean(genjet, genMu, drmin=0.4) & te_os.isClean(genjet, genPhoton, drmin=0.1)
genjet_clean = genjet[is_clean_jet]

genjets_num_mask = ak.num(genjet_clean) >= 1 #Require that there is at least 1 jet

################## Gen matched b jets selection ########################
genbJets_mask = np.abs(genjet_clean.hadronFlavour)==5 #bjet selection from genJet collection
genbJets = genJet[genbJets_mask]
genbJets_pT_eta_mask = ((genbJets.pt > 30) & (abs(genbJets.eta) < 2.44))
genbJets_pT_eta_mask = ak.fill_none(ak.pad_none(genbJets_pT_eta_mask,1),False)
genbJets = genbJets[genbJets_pT_eta_mask]

#gen bJet multiplicity mask
genbJets_num_mask = ak.num(genbJets) >= 1 #Require that there is at least 1 btagged jet

################### Define dense axis variables #######################
genphoton_pt = ak.fill_none(ak.firsts(genPhoton.pt),-1) #highest pt in the genphoton collection
genl0pt = ak.fill_none(ak.firsts(genleps_ptsorted.pt),-1) #highest pt in the genlep collection

# Dictionary of dense axis values
dense_axis_dict = {
"genphoton_pt" : genphoton_pt,
"genlep_pt" : genl0pt,
}

#### Get weights ###
# Extract the EFT quadratic coefficients and optionally use them to calculate the coefficients on the w**2 quartic function
# eft_coeffs is never Jagged so convert immediately to numpy for ease of use.
eft_coeffs = ak.to_numpy(events["EFTfitCoefficients"]) if hasattr(events, "EFTfitCoefficients") else None
if eft_coeffs is not None:
# Check to see if the ordering of WCs for this process matches what want
if self._processs[dataset]["WCnames"] != self._wc_names_lst:
eft_coeffs = efth.remap_coeffs(self._processs[dataset]["WCnames"], self._wc_names_lst, eft_coeffs)
eft_w2_coeffs = efth.calc_w2_coeffs(eft_coeffs,self._dtype) if (self._do_errors and eft_coeffs is not None) else None

#If this is not an eft process, get the genWeight
if eft_coeffs is None: genw = events["genWeight"]
else: genw = np.ones_like(events["event"])
lumi = 1000.0*get_tc_param(f"lumi_{year}")
event_weight = lumi*(xsec/sow)*genw

#Final mask relevant to the "category" we are interested in.
#genph_2lOS_mask = (genleps_num_mask & genleps_chargesum_zero & genjets_num_mask & genbJets_num_mask & events.genPhoton_pT_eta_mask & genphoton_num_mask)
genphoton_2lOS_mask = (all_genleps_mask & genjets_num_mask & genbJets_num_mask & genphoton_num_mask)
nogenphoton_2lOS_mask = (all_genleps_mask & genjets_num_mask & genbJets_num_mask)

##### Loop over the hists we want to fill ###########

hout = self.accumulator.identity()

for dense_axis_name, dense_axis_vals in dense_axis_dict.items():

#Mask out the none values
isnotnone_mask = (ak.fill_none((dense_axis_vals != None),False))
#all_cuts_mask = ak.any(genph_2lOS_mask,axis=1)# & isnotnone_mask)
if dense_axis_name == "genphoton_pt":
all_cuts_mask = genphoton_2lOS_mask
elif dense_axis_name == "genlep_pt":
all_cuts_mask = nogenphoton_2lOS_mask
dense_axis_vals_cut = dense_axis_vals[all_cuts_mask]
event_weights_cut = event_weight[all_cuts_mask]
eft_coeffs_cut = eft_coeffs
if eft_coeffs is not None: eft_coeffs_cut = eft_coeffs[all_cuts_mask]
eft_w2_coeffs_cut = eft_w2_coeffs
if eft_w2_coeffs is not None: eft_w2_coeffs_cut = eft_w2_coeffs[all_cuts_mask]

# Fill the histos
axes_fill_info_dict = {
dense_axis_name : dense_axis_vals_cut,
"process" : histAxisName,
"weight" : event_weights_cut,
"eft_coeff" : eft_coeffs_cut,
"eft_err_coeff" : eft_w2_coeffs_cut,
}

hout[dense_axis_name].fill(**axes_fill_info_dict)

return hout

def postprocess(self, accumulator):
return accumulator
9 changes: 8 additions & 1 deletion analysis/topeft_run2/make_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def run_condor(dc,pkl_fpath,out_dir,var_lst,ch_lst,chunk_size):
other_opts.append("--do-nuisance")
if dc.year_lst:
other_opts.extend(["--year"," ".join(dc.year_lst)])
if dc.use_AAC:
other_opts.append("--use-AAC")
if dc.do_ttA:
other_opts.append("--do-ttA")
if dc.drop_syst:
other_opts.extend(["--drop-syst"," ".join(dc.drop_syst)])
other_opts = " ".join(other_opts)
Expand Down Expand Up @@ -173,6 +177,7 @@ def main():
parser.add_argument("--use-AAC","-A",action="store_true",help="Include all EFT templates in datacards for AAC model")
parser.add_argument("--wc-vals", default="",action="store", nargs="+", help="Specify the corresponding wc values to set for the wc list")
parser.add_argument("--wc-scalings", default=[],action="extend",nargs="+",help="Specify a list of wc ordering for scalings.json")
parser.add_argument("--do-ttA", action="store_true",help="If runnning over ttA channels, use this")

args = parser.parse_args()
pkl_file = args.pkl_file
Expand All @@ -191,6 +196,7 @@ def main():
verbose = args.verbose
use_AAC = args.use_AAC
wc_vals = args.wc_vals
do_ttA = args.do_ttA

wc_scalings = args.wc_scalings
select_only = args.select_only
Expand All @@ -205,7 +211,7 @@ def main():
kwargs = {
"wcs": wcs,
"rate_syst_path": rs_json,
"missing_parton_path": mp_file,
#"missing_parton_path": mp_file,
"out_dir": out_dir,
"var_lst": var_lst,
"do_mc_stat": do_mc_stat,
Expand All @@ -218,6 +224,7 @@ def main():
"use_AAC": use_AAC,
"wc_vals": wc_vals,
"wc_scalings": wc_scalings,
"do_ttA": do_ttA,
}

if out_dir != "." and not os.path.exists(out_dir):
Expand Down
Loading
Loading