29
29
30
30
# Argument parsing
31
31
parser = argparse .ArgumentParser ()
32
- parser .add_argument ("--lumi-scale" , type = float , default = 0.001 ,
33
- help = "Run only on a fraction of the total available 10 fb^-1 (only usable together with --full-dataset)" )
34
- parser .add_argument ("--full-dataset" , action = "store_true" , default = False ,
35
- help = "Use the full dataset (use --lumi-scale to run only on a fraction of it)" )
32
+ parser .add_argument (
33
+ "--lumi-scale" ,
34
+ type = float ,
35
+ default = 0.001 ,
36
+ help = "Run only on a fraction of the total available 10 fb^-1 (only usable together with --full-dataset)" ,
37
+ )
38
+ parser .add_argument (
39
+ "--full-dataset" ,
40
+ action = "store_true" ,
41
+ default = False ,
42
+ help = "Use the full dataset (use --lumi-scale to run only on a fraction of it)" ,
43
+ )
36
44
parser .add_argument ("-b" , action = "store_true" , default = False , help = "Use ROOT batch mode" )
37
- parser .add_argument ("-t" , action = "store_true" , default = False , help = "Use implicit multi threading (for the full dataset only possible with --lumi-scale 1.0)" )
38
- if 'df105.py' in sys .argv [0 ]:
45
+ parser .add_argument (
46
+ "-t" ,
47
+ action = "store_true" ,
48
+ default = False ,
49
+ help = "Use implicit multi threading (for the full dataset only possible with --lumi-scale 1.0)" ,
50
+ )
51
+ if "df105.py" in sys .argv [0 ]:
39
52
# Script
40
53
args = parser .parse_args ()
41
54
else :
42
55
# Notebook
43
56
args = parser .parse_args (args = [])
44
57
45
- if args .b : ROOT .gROOT .SetBatch (True )
46
- if args .t : ROOT .EnableImplicitMT ()
58
+ if args .b :
59
+ ROOT .gROOT .SetBatch (True )
60
+ if args .t :
61
+ ROOT .EnableImplicitMT ()
47
62
48
- if not args .full_dataset : lumi_scale = 0.001 # The preskimmed dataset contains only 0.01 fb^-1
49
- else : lumi_scale = args .lumi_scale
63
+ if not args .full_dataset :
64
+ lumi_scale = 0.001 # The preskimmed dataset contains only 0.01 fb^-1
65
+ else :
66
+ lumi_scale = args .lumi_scale
50
67
lumi = 10064.0
51
- print (' Run on data corresponding to {:.2f} fb^-1 ...' .format (lumi * lumi_scale / 1000.0 ))
68
+ print (" Run on data corresponding to {:.2f} fb^-1 ..." .format (lumi * lumi_scale / 1000.0 ))
52
69
53
- if args .full_dataset : dataset_path = "root://eospublic.cern.ch//eos/opendata/atlas/OutreachDatasets/2020-01-22"
54
- else : dataset_path = "root://eospublic.cern.ch//eos/root-eos/reduced_atlas_opendata/w"
70
+ if args .full_dataset :
71
+ dataset_path = "root://eospublic.cern.ch//eos/opendata/atlas/OutreachDatasets/2020-01-22"
72
+ else :
73
+ dataset_path = "root://eospublic.cern.ch//eos/root-eos/reduced_atlas_opendata/w"
55
74
56
75
# Create a ROOT dataframe for each dataset
57
76
# Note that we load the filenames from the external json file placed in the same folder than this script.
64
83
for p in processes :
65
84
for d in files [p ]:
66
85
# Construct the dataframes
67
- folder = d [0 ] # Folder name
68
- sample = d [1 ] # Sample name
69
- xsecs [sample ] = d [2 ] # Cross-section
70
- sumws [sample ] = d [3 ] # Sum of weights
71
- num_events = d [4 ] # Number of events
86
+ folder = d [0 ] # Folder name
87
+ sample = d [1 ] # Sample name
88
+ xsecs [sample ] = d [2 ] # Cross-section
89
+ sumws [sample ] = d [3 ] # Sum of weights
90
+ num_events = d [4 ] # Number of events
72
91
samples .append (sample )
73
92
df [sample ] = ROOT .RDataFrame ("mini" , "{}/1lep/{}/{}.1lep.root" .format (dataset_path , folder , sample ))
74
93
98
117
99
118
for s in samples :
100
119
# Select events with a muon or electron trigger and with a missing transverse energy larger than 30 GeV
101
- df [s ] = df [s ].Filter ("trigE || trigM" )\
102
- .Filter ("met_et > 30000" )
120
+ df [s ] = df [s ].Filter ("trigE || trigM" ).Filter ("met_et > 30000" )
103
121
104
122
# Find events with exactly one good lepton
105
- df [s ] = df [s ].Define ("good_lep" , "lep_isTightID && lep_pt > 35000 && lep_ptcone30 / lep_pt < 0.1 && lep_etcone20 / lep_pt < 0.1" )\
106
- .Filter ("ROOT::VecOps::Sum(good_lep) == 1" )
123
+ df [s ] = (
124
+ df [s ]
125
+ .Define (
126
+ "good_lep" , "lep_isTightID && lep_pt > 35000 && lep_ptcone30 / lep_pt < 0.1 && lep_etcone20 / lep_pt < 0.1"
127
+ )
128
+ .Filter ("ROOT::VecOps::Sum(good_lep) == 1" )
129
+ )
107
130
108
131
# Apply additional cuts in case the lepton is an electron or muon
109
- df [s ] = df [s ].Define ("idx" , "ROOT::VecOps::ArgMax(good_lep)" )\
110
- .Filter ("GoodElectronOrMuon(lep_type[idx], lep_pt[idx], lep_eta[idx], lep_phi[idx], lep_E[idx], lep_trackd0pvunbiased[idx], lep_tracksigd0pvunbiased[idx], lep_z0[idx])" )
132
+ df [s ] = (
133
+ df [s ]
134
+ .Define ("idx" , "ROOT::VecOps::ArgMax(good_lep)" )
135
+ .Filter (
136
+ "GoodElectronOrMuon(lep_type[idx], lep_pt[idx], lep_eta[idx], lep_phi[idx], lep_E[idx], lep_trackd0pvunbiased[idx], lep_tracksigd0pvunbiased[idx], lep_z0[idx])"
137
+ )
138
+ )
111
139
112
140
# Apply luminosity, scale factors and MC weights for simulated events
113
141
for s in samples :
114
142
if "data" in s :
115
143
df [s ] = df [s ].Define ("weight" , "1.0" )
116
144
else :
117
- df [s ] = df [s ].Define ("weight" , "scaleFactor_ELE * scaleFactor_MUON * scaleFactor_LepTRIGGER * scaleFactor_PILEUP * mcWeight * {} / {} * {}" .format (xsecs [s ], sumws [s ], lumi ))
145
+ df [s ] = df [s ].Define (
146
+ "weight" ,
147
+ "scaleFactor_ELE * scaleFactor_MUON * scaleFactor_LepTRIGGER * scaleFactor_PILEUP * mcWeight * {} / {} * {}" .format (
148
+ xsecs [s ], sumws [s ], lumi
149
+ ),
150
+ )
118
151
119
152
# Compute transverse mass of the W boson using the lepton and the missing transverse energy and make a histogram
120
153
ROOT .gInterpreter .Declare ("""
128
161
129
162
histos = {}
130
163
for s in samples :
131
- df [s ] = df [s ].Define ("mt_w" , "ComputeTransverseMass(met_et, met_phi, lep_pt[idx], lep_eta[idx], lep_phi[idx], lep_E[idx])" )
164
+ df [s ] = df [s ].Define (
165
+ "mt_w" , "ComputeTransverseMass(met_et, met_phi, lep_pt[idx], lep_eta[idx], lep_phi[idx], lep_E[idx])"
166
+ )
132
167
histos [s ] = df [s ].Histo1D (ROOT .RDF .TH1DModel (s , "mt_w" , 24 , 60 , 180 ), "mt_w" , "weight" )
133
168
134
169
# Run the event loop and merge histograms of the respective processes
139
174
# because not enough data is available.
140
175
ROOT .RDF .RunGraphs ([histos [s ] for s in samples ])
141
176
177
+
142
178
def merge_histos (label ):
143
179
h = None
144
180
for i , d in enumerate (files [label ]):
145
181
t = histos [d [1 ]].GetValue ()
146
- if i == 0 : h = t .Clone ()
147
- else : h .Add (t )
182
+ if i == 0 :
183
+ h = t .Clone ()
184
+ else :
185
+ h .Add (t )
148
186
h .SetNameTitle (label , label )
149
187
return h
150
188
189
+
151
190
data = merge_histos ("data" )
152
191
wjets = merge_histos ("wjets" )
153
192
zjets = merge_histos ("zjets" )
@@ -178,7 +217,7 @@ def merge_histos(label):
178
217
frame .x .labels .size = 0.04
179
218
180
219
frame .y .min = 1
181
- frame .y .max = 1e10 * args .lumi_scale
220
+ frame .y .max = 1e10 * args .lumi_scale
182
221
frame .y .log = 10
183
222
frame .y .title .value = "Events"
184
223
frame .y .title .size = 0.045
@@ -190,8 +229,9 @@ def merge_histos(label):
190
229
# Draw stack with MC contributions
191
230
stack = ROOT .THStack ()
192
231
for h , color in zip (
193
- [singletop , diboson , ttbar , zjets , wjets ],
194
- [(0.82 , 0.94 , 0.76 ), (0.76 , 0.54 , 0.57 ), (0.61 , 0.6 , 0.8 ), (0.97 , 0.81 , 0.41 ), (0.87 , 0.35 , 0.42 )]):
232
+ [singletop , diboson , ttbar , zjets , wjets ],
233
+ [(0.82 , 0.94 , 0.76 ), (0.76 , 0.54 , 0.57 ), (0.61 , 0.6 , 0.8 ), (0.97 , 0.81 , 0.41 ), (0.87 , 0.35 , 0.42 )],
234
+ ):
195
235
h .SetLineWidth (1 )
196
236
h .SetLineColor ("black" )
197
237
h .SetFillColor (ROOT .TColor .GetColor (* color ))
@@ -214,7 +254,7 @@ def merge_histos(label):
214
254
legend .SetBorderSize (0 )
215
255
legend .SetTextSize (0.04 )
216
256
legend .SetTextAlign (32 )
217
- legend .AddEntry (data , "Data" , "lep" )
257
+ legend .AddEntry (data , "Data" , "lep" )
218
258
legend .AddEntry (wjets , "W+jets" , "f" )
219
259
legend .AddEntry (zjets , "Z+jets" , "f" )
220
260
legend .AddEntry (ttbar , "t#bar{t}" , "f" )
@@ -233,7 +273,9 @@ def merge_histos(label):
233
273
lbl2 .text .font = RAttrFont .kArial
234
274
lbl2 .text .size = 0.04
235
275
lbl2 .text .align = RAttrText .kLeftBottom
236
- lbl3 = c .Add [RText ](RPadPos (0.05 , 0.82 ), "#sqrt{{s}} = 13 TeV, {:.2f} fb^{{-1}}" .format (lumi * args .lumi_scale / 1000.0 ))
276
+ lbl3 = c .Add [RText ](
277
+ RPadPos (0.05 , 0.82 ), "#sqrt{{s}} = 13 TeV, {:.2f} fb^{{-1}}" .format (lumi * args .lumi_scale / 1000.0 )
278
+ )
237
279
lbl3 .onFrame = True
238
280
lbl3 .text .font = RAttrFont .kArial
239
281
lbl3 .text .size = 0.03
@@ -244,5 +286,5 @@ def merge_histos(label):
244
286
c .Show ()
245
287
246
288
# Save the plot
247
- if c .SaveAs ("df105.png" ) :
289
+ if c .SaveAs ("df105.png" ):
248
290
print ("Saved figure to df105.png" )
0 commit comments