Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,49 @@ def __fill_defaults__( self ):
self.include_higgs = False

self.luminosity_scale = self.new_luminosity / self.luminosity

self.typical_systematics = {
"typical_systematics_electron": ['Electron_down',
'Electron_up'],
"typical_systematics_muon": ['Muon_down',
'Muon_up'],
"typical_systematics_btagging": ['BJet_down',
'BJet_up'],
"typical_systematics_JES": ['JES_down',
'JES_up'],
"typical_systematics_JER": ['JER_down',
'JER_up'],
"typical_systematics_PU": ['PU_down',
'PU_up'],
"typical_systematics_hadronisation": ['hadronisation'],
"typical_systematics_QCD_shape": ['QCD_shape'],
"typical_systematics_PDF": ['PDF_total_lower',
'PDF_total_upper'],
"typical_systematics_top_mass": ['TTJets_massdown',
'TTJets_massup'],
"typical_systematics_background_other": ["TTJet_cross_section+",
"TTJet_cross_section-",
"SingleTop_cross_section+",
"SingleTop_cross_section-",
"luminosity+",
"luminosity-"],
"typical_systematics_theoretical": ["TTJets_matchingup",
"TTJets_matchingdown",
"VJets_matchingup",
'VJets_matchingdown',
"TTJets_scaleup",
"TTJets_scaledown",
"VJets_scaleup",
"VJets_scaledown"],
"typical_systematics_MET": ["patType1CorrectedPFMetElectronEnUp",
"patType1CorrectedPFMetElectronEnDown",
"patType1CorrectedPFMetMuonEnUp",
"patType1CorrectedPFMetMuonEnDown",
"patType1CorrectedPFMetTauEnUp",
"patType1CorrectedPFMetTauEnDown",
"patType1CorrectedPFMetUnclusteredEnUp",
"patType1CorrectedPFMetUnclusteredEnDown"]
}

def __fill_defaults_7TeV__( self ):
middle = self.middle
Expand Down
15 changes: 15 additions & 0 deletions config/latex_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,18 @@
'M_bl' : r'$M(b,l)$',
'angle_bl' : r'angle$(b,l)$',
}

typical_systematics_latex = {"typical_systematics_electron": "Trigger efficiency \& electron selection",
"typical_systematics_muon": "Trigger efficiency \& muon selection",
"typical_systematics_btagging": "btagging",
"typical_systematics_JES": "Jet Energy Scale",
"typical_systematics_JER": "Jet Energy Resolution",
"typical_systematics_PU": "pileup",
"typical_systematics_hadronisation": "hadronisation",
"typical_systematics_QCD_shape": "QCD shape",
"typical_systematics_PDF": "PDF uncertainties",
"typical_systematics_top_mass": "top mass",
"typical_systematics_theoretical": "Theoretical systematics",
'typical_systematics_background_other': 'Background (other)',
'typical_systematics_MET': '$E_{T}^{miss}$ uncertainties'
}
2 changes: 1 addition & 1 deletion src/cross_section_measurement/02_unfold_and_measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ def calculate_normalised_xsections( normalisation, category, channel, k_value =
categories.extend( vjets_generator_systematics )

# ttbar theory systematics, including pt reweighting and hadronisation systematic
ttbar_theory_systematics = [] #[ ttbar_theory_systematic_prefix + 'ptreweight' ]
ttbar_theory_systematics = [ ttbar_theory_systematic_prefix + 'ptreweight' ]
ttbar_theory_systematics.extend( [ttbar_theory_systematic_prefix + 'powheg_pythia', ttbar_theory_systematic_prefix + 'powheg_herwig'] )
categories.extend( ttbar_theory_systematics )

Expand Down
12 changes: 6 additions & 6 deletions src/cross_section_measurement/03_calculate_systematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def replace_measurement_with_deviation_from_central( central_measurement, dictio
kValue_systematic_list = measurement_config.kValueSystematic

# ttbar theory systematics: ptreweighting, hadronisation systematic (powheg_pythia - powheg_herwig)
# ttbar_ptreweight_systematic_list = [ttbar_theory_systematic_prefix + 'ptreweight']
ttbar_ptreweight_systematic_list = [ttbar_theory_systematic_prefix + 'ptreweight']
ttbar_hadronisation_systematic_list = [ttbar_theory_systematic_prefix + 'powheg_pythia', ttbar_theory_systematic_prefix + 'powheg_herwig']

# 45 PDF uncertainties
Expand All @@ -237,7 +237,7 @@ def replace_measurement_with_deviation_from_central( central_measurement, dictio

# read groups of systematics
ttbar_generator_systematics, ttbar_generator_systematics_unfolded = read_normalised_xsection_systematics( list_of_systematics = ttbar_generator_systematics_list, channel = channel )
# ttbar_ptreweight_systematic, ttbar_ptreweight_systematic_unfolded = read_normalised_xsection_systematics( list_of_systematics = ttbar_ptreweight_systematic_list, channel = channel )
ttbar_ptreweight_systematic, ttbar_ptreweight_systematic_unfolded = read_normalised_xsection_systematics( list_of_systematics = ttbar_ptreweight_systematic_list, channel = channel )
ttbar_hadronisation_systematic, ttbar_hadronisation_systematic_unfolded = read_normalised_xsection_systematics( list_of_systematics = ttbar_hadronisation_systematic_list, channel = channel )
# top mass systematic
ttbar_mass_systematic, ttbar_mass_systematic_unfolded = read_normalised_xsection_systematics( list_of_systematics = ttbar_mass_systematics_list, channel = channel )
Expand All @@ -251,8 +251,8 @@ def replace_measurement_with_deviation_from_central( central_measurement, dictio
ttbar_generator_min, ttbar_generator_max = summarise_systematics( central_measurement, ttbar_generator_systematics )
ttbar_generator_min_unfolded, ttbar_generator_max_unfolded = summarise_systematics( central_measurement_unfolded, ttbar_generator_systematics_unfolded )
# ttbar theory systematics (pt reweighting and hadronisation)
# ttbar_ptreweight_min, ttbar_ptreweight_max = summarise_systematics( central_measurement, ttbar_ptreweight_systematic )
# ttbar_ptreweight_min_unfolded, ttbar_ptreweight_max_unfolded = summarise_systematics( central_measurement_unfolded, ttbar_ptreweight_systematic_unfolded )
ttbar_ptreweight_min, ttbar_ptreweight_max = summarise_systematics( central_measurement, ttbar_ptreweight_systematic )
ttbar_ptreweight_min_unfolded, ttbar_ptreweight_max_unfolded = summarise_systematics( central_measurement_unfolded, ttbar_ptreweight_systematic_unfolded )
ttbar_hadronisation_min, ttbar_hadronisation_max = summarise_systematics( central_measurement, ttbar_hadronisation_systematic, hadronisation_systematic = True )
ttbar_hadronisation_min_unfolded, ttbar_hadronisation_max_unfolded = summarise_systematics( central_measurement_unfolded, ttbar_hadronisation_systematic_unfolded, hadronisation_systematic = True )
# Top mass systematic
Expand Down Expand Up @@ -395,8 +395,8 @@ def replace_measurement_with_deviation_from_central( central_measurement, dictio
new_systematics['hadronisation'] = ttbar_hadronisation_min #( == ttbar_hadronisation_max)
new_systematics_unfolded['hadronisation'] = ttbar_hadronisation_min_unfolded #( == ttbar_hadronisation_max_unfolded)

# new_systematics['ptreweight_min'], new_systematics['ptreweight_max'] = ttbar_ptreweight_min, ttbar_ptreweight_max
# new_systematics_unfolded['ptreweight_min'], new_systematics_unfolded['ptreweight_max'] = ttbar_ptreweight_min_unfolded, ttbar_ptreweight_max_unfolded
new_systematics['ptreweight_min'], new_systematics['ptreweight_max'] = ttbar_ptreweight_min, ttbar_ptreweight_max
new_systematics_unfolded['ptreweight_min'], new_systematics_unfolded['ptreweight_max'] = ttbar_ptreweight_min_unfolded, ttbar_ptreweight_max_unfolded

write_normalised_xsection_measurement( ttbar_generator_systematics, ttbar_generator_systematics_unfolded, channel, summary = 'ttbar_generator' )
write_normalised_xsection_measurement( pdf_systematics, pdf_systematics_unfolded, channel, summary = 'PDF' )
Expand Down
152 changes: 150 additions & 2 deletions src/cross_section_measurement/05_make_tables.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from __future__ import division # the result of the division will be always a float
from optparse import OptionParser
from copy import deepcopy
from config.latex_labels import variables_latex, measurements_latex, met_systematics_latex, samples_latex
from config.latex_labels import variables_latex, measurements_latex, met_systematics_latex, samples_latex, typical_systematics_latex
from config.variable_binning import variable_bins_latex, variable_bins_ROOT
from config import XSectionConfig
from tools.Calculation import getRelativeError
from tools.file_utilities import read_data_from_JSON, make_folder_if_not_exists
from lib import read_fit_results, read_fit_input
import math
import os.path
from numpy import median

def read_xsection_measurement_results_with_errors(channel):
global path_to_JSON, variable, k_values, met_type
Expand Down Expand Up @@ -357,7 +359,6 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
else:
rows[source] = [measurements_latex[source] + ' (\%)', text]


header += ' \\\\'
printout += header
printout += '\n\\hline\n'
Expand Down Expand Up @@ -400,6 +401,148 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
output_file.close()
else:
print printout

def print_typical_systematics_table(central_values, errors, channel, toFile = True, print_before_unfolding = False):
global output_folder, variable, k_values, met_type, b_tag_bin, all_measurements
bins = variable_bins_ROOT[variable]

values_for_typical_systematics_table = {}

assert(len(bins) == len(errors['central']))
if print_before_unfolding:
assert(len(bins) == len(central_values['measured']))
else:
assert(len(bins) == len(central_values['unfolded']))

for bin_i, variable_bin in enumerate(bins):
if print_before_unfolding:
central_value = central_values['measured'][bin_i][0]
else:
central_value = central_values['unfolded'][bin_i][0]

for systematic_group in typical_systematics.keys():
for source in all_measurements:
if source in typical_systematics[systematic_group]:
abs_error = errors[source][bin_i]
relative_error = getRelativeError(central_value, abs_error)
value = relative_error
if values_for_typical_systematics_table.has_key(source):
values_for_typical_systematics_table[source].append(value)
else:
values_for_typical_systematics_table[source] = [typical_systematics_latex[systematic_group] + ' (\%)', value]

rows_for_typical_systematics_table = {}

if variable == "HT":
del(typical_systematics["typical_systematics_MET"])
for systematic_group in typical_systematics.keys():
typical_systematics_row = []
typical_systematics_row.append(typical_systematics_latex[systematic_group] + ' (\%)')
for bin_i, variable_bin in enumerate(bins):
sum = 0.

#if only one systematic in the group, in each bin just use the systematic value (absolute)
if len(typical_systematics[systematic_group]) == 1:
sum += abs(values_for_typical_systematics_table[typical_systematics[systematic_group][0]][bin_i+1])

#if two systematics in the group, in each bin use the largest of the two absolute values
elif len(typical_systematics[systematic_group]) == 2:
low_syst = abs(values_for_typical_systematics_table[typical_systematics[systematic_group][0]][bin_i+1])
high_syst = abs(values_for_typical_systematics_table[typical_systematics[systematic_group][1]][bin_i+1])
sum += max(low_syst, high_syst)

#if more than two systematics in the group, take the maximum of each pair of up/down systematics, and add these maximum values for all systematics in quadrature
else:
for systematic in typical_systematics [systematic_group]:
index_in_group = typical_systematics[systematic_group].index(systematic)
if index_in_group %2 == 1 : #if not 0th, 2nd, 4th etc. element of list, get out of loop
continue
else:
low_syst = abs(values_for_typical_systematics_table[typical_systematics[systematic_group][index_in_group]][bin_i+1])
high_syst = abs(values_for_typical_systematics_table[typical_systematics[systematic_group][index_in_group+1]][bin_i+1])
largest = max(low_syst, high_syst) #(values_for_typical_systematics_table[systematic][bin_i+1])
sum += pow(largest, 2)
sum = math.sqrt(sum)

typical_systematics_row.append(sum)
label = typical_systematics_row.pop(0)

#for each systematic group, take the median of the values across all bins
value = median(typical_systematics_row)
text = '%.2f' % (value*100)
rows_for_typical_systematics_table[systematic_group] = [label, text]

printout = '%% ' + '=' * 60
printout += '\n'
printout += '%% Typical systematics table for %s variable, %s channel, k-value %s, met type %s, %s b-tag region\n' % (variable, channel, str(k_values[channel]), met_type, b_tag_bin)
if print_before_unfolding:
printout += '%% BEFORE UNFOLDING\n'
printout += '%% ' + '=' * 60
printout += '\n'

printout += '\\begin{table}[htbp]\n'
printout += '\\centering\n'
printout += '\\caption{Typical systematic uncertainties (median values) for the normalised \\ttbar cross section measurement \n'
printout += 'at a centre-of-mass energy of %d TeV ' % measurement_config.centre_of_mass_energy
if channel == 'combined':
printout += '(combination of electron and muon channels).}\n'
else:
printout += '(%s channel).}\n' % channel
printout += '\\label{tab:typical_systematics_%dTeV_%s}\n' % (measurement_config.centre_of_mass_energy, channel)
printout += '\\resizebox{\\columnwidth}{!} {\n'
printout += '\\begin{tabular}{l' + 'r'*len(variable_bins_ROOT) + '}\n'
printout += '\\hline\n'

header = 'Uncertainty source '
header += '& %s' % (variables_latex[variable])

header += ' \\\\'
printout += header
printout += '\n\\hline\n'

for systematic_group in sorted(rows_for_typical_systematics_table.keys()):
if systematic_group == 'central':
continue
for item in rows_for_typical_systematics_table[systematic_group]:
printout += item + ' & '
printout = printout.rstrip('& ')
printout += ' \\\\ \n'

printout += '\\hline \n'
printout += '\\hline \n'
printout += '\\end{tabular}\n'
printout += '}\n'
printout += '\\end{table}\n'

if toFile:
path = output_folder + '/' + str(measurement_config.centre_of_mass_energy) + 'TeV/'
make_folder_if_not_exists(path)
file_template = path + '/typical_systematics_%dTeV_%s.tex' % (measurement_config.centre_of_mass_energy, channel)

if print_before_unfolding:
make_folder_if_not_exists(path + '/before_unfolding/')
file_template = file_template.replace(path, path + '/before_unfolding/')
if os.path.isfile(file_template):
with open(file_template, 'r+') as output_file:
lines = output_file.readlines()
for line_number, line in enumerate (lines):
if line.startswith("Uncertainty source"):
lines[line_number] = lines[line_number].strip() + "& " + variables_latex[variable] + "\n"
elif variable == "HT" and line.startswith("$E_{T}^{miss}$ uncertainties"):
lines[line_number] = lines[line_number].strip() + "& - \n"
else:
for table_entry in enumerate(typical_systematics_latex):
if line.startswith(typical_systematics_latex[table_entry[1]]):
lines[line_number] = lines[line_number].strip() + "& " + rows_for_typical_systematics_table[table_entry[1]][1] + " \n"
output_file.seek(0)
for line in lines:
output_file.write(line)
else:
output_file = open(file_template, 'w')
output_file.write(printout)
output_file.close()
else:
print printout

if __name__ == '__main__':
parser = OptionParser()
Expand All @@ -425,6 +568,7 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
ttbar_theory_systematic_prefix = measurement_config.ttbar_theory_systematic_prefix
vjets_theory_systematic_prefix = measurement_config.vjets_theory_systematic_prefix
met_systematics_suffixes = measurement_config.met_systematics_suffixes
typical_systematics = measurement_config.typical_systematics

variable = options.variable
output_folder = options.output_folder
Expand Down Expand Up @@ -479,6 +623,10 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
print_error_table(normalised_xsection_measured_unfolded, normalised_xsection_unfolded_errors, channel, toFile = True, print_before_unfolding = False)
print_error_table(normalised_xsection_measured_unfolded, normalised_xsection_measured_errors, channel, toFile = True, print_before_unfolding = True)

if channel == 'combined':
print_typical_systematics_table(normalised_xsection_measured_unfolded, normalised_xsection_unfolded_errors, channel, toFile = True, print_before_unfolding = False)
# print_typical_systematics_table(normalised_xsection_measured_unfolded, normalised_xsection_measured_errors, channel, toFile = True, print_before_unfolding = True)

if not channel == 'combined':
fit_input = read_fit_input(path_to_JSON, variable, 'central', channel, met_type)
fit_results = read_fit_results(path_to_JSON, variable, 'central', channel, met_type)
Expand Down
1 change: 0 additions & 1 deletion tools/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
'''
import matplotlib as mpl
from tools.file_utilities import make_folder_if_not_exists
from tkFont import names
from tools.hist_utilities import get_histogram_ratios, spread_x
mpl.use('agg')
import matplotlib.pyplot as plt
Expand Down