11from __future__ import division # the result of the division will be always a float
22from optparse import OptionParser
33from copy import deepcopy
4- from config .latex_labels import variables_latex , measurements_latex , samples_latex , typical_systematics_latex , met_systematics_latex
5- from config .variable_binning import variable_bins_latex , variable_bins_ROOT , variable_bins_visiblePS_ROOT , variable_bins_visiblePS_latex
4+ from config .latex_labels import variables_latex , variables_NonLatex , measurements_latex , samples_latex , typical_systematics_latex , met_systematics_latex
5+ from config .variable_binning import variable_bins_latex , variable_bins_ROOT , variable_bins_visiblePS_ROOT , variable_bins_visiblePS_latex , bin_edges_vis , bin_edges
66from config import XSectionConfig
77from tools .Calculation import getRelativeError
88from tools .file_utilities import read_data_from_JSON , make_folder_if_not_exists
9+ from tools .hist_utilities import values_and_errors_to_hist
910from lib import read_normalisation , read_initial_normalisation
1011import math
1112import os .path
1213from numpy import median
14+ import matplotlib as mpl
15+ mpl .use ( 'agg' )
16+ import matplotlib .pyplot as plt
17+ import rootpy .plotting .root2matplotlib as rplt
18+ from config import CMS
19+ import matplotlib .cm as cm
20+ # use full stpectrum, yet use white for less than vmin=1 events
21+ my_cmap = cm .get_cmap ( 'jet' )
22+ my_cmap .set_under ( 'w' )
23+ from matplotlib import rc
24+ rc ( 'font' , ** CMS .font )
25+ rc ( 'text' , usetex = False )
1326
1427def read_xsection_measurement_results_with_errors (channel ):
1528 global path_to_JSON , variable , met_type , phase_space
@@ -40,6 +53,9 @@ def read_xsection_measurement_results_with_errors(channel):
4053 file_name = file_template .replace ('.txt' , '_PDF_errors.txt' )
4154 normalised_xsection_PDF_errors = read_data_from_JSON ( file_name )
4255
56+ file_name = file_template .replace ('.txt' , '_experimental_errors.txt' )
57+ normalised_xsection_experimental_errors = read_data_from_JSON ( file_name )
58+
4359 file_name = file_template .replace ('.txt' , '_other_errors.txt' )
4460 normalised_xsection_other_errors = read_data_from_JSON ( file_name )
4561
@@ -59,7 +75,7 @@ def read_xsection_measurement_results_with_errors(channel):
5975# normalised_xsection_measured_errors.update(normalised_xsection_MET_errors['TTJet_measured'])
6076# normalised_xsection_measured_errors.update(normalised_xsection_topMass_errors['TTJet_measured'])
6177 ### normalised_xsection_measured_errors.update(normalised_xsection_kValue_errors['TTJet_measured'])
62- normalised_xsection_measured_errors .update (normalised_xsection_other_errors ['TTJet_measured' ])
78+ normalised_xsection_measured_errors .update (normalised_xsection_experimental_errors ['TTJet_measured' ])
6379# normalised_xsection_measured_errors.update(normalised_xsection_new_errors['TTJet_measured'])
6480
6581 normalised_xsection_unfolded_errors = normalised_xsection_other_errors ['TTJet_unfolded' ]
@@ -68,7 +84,7 @@ def read_xsection_measurement_results_with_errors(channel):
6884# normalised_xsection_unfolded_errors.update(normalised_xsection_MET_errors['TTJet_unfolded'])
6985# normalised_xsection_unfolded_errors.update(normalised_xsection_topMass_errors['TTJet_unfolded'])
7086 ### normalised_xsection_unfolded_errors.update(normalised_xsection_kValue_errors['TTJet_unfolded'])
71- normalised_xsection_unfolded_errors .update (normalised_xsection_other_errors ['TTJet_unfolded' ])
87+ normalised_xsection_unfolded_errors .update (normalised_xsection_experimental_errors ['TTJet_unfolded' ])
7288# normalised_xsection_unfolded_errors.update(normalised_xsection_new_errors['TTJet_unfolded'])
7389
7490 return normalised_xsection_measured_unfolded , normalised_xsection_measured_errors , normalised_xsection_unfolded_errors
@@ -322,18 +338,102 @@ def print_xsections(xsections, channel, toFile = True, print_before_unfolding =
322338 else :
323339 print printout
324340
341+ def make_error_plot ( errorHists , bins ):
342+ global output_folder , variable
343+ # For each up/down source, reduce to one set of numbers
344+ symmetricErrorHists = {}
345+ for source , hist in errorHists .iteritems ():
346+ if ( variable == 'HT' or variable == 'NJets' or variable == 'lepton_pt' or variable == 'abs_lepton_eta' ) and source in measurement_config .met_systematics and not 'JES' in source and not 'JER' in source :
347+ continue
348+
349+ if 'down' in source or '-' in source or 'lower' in source or 'Down' in source :
350+ # Find up version
351+ upHist = None
352+ newSource = ''
353+ if 'down' in source :
354+ upHist = errorHists [source .replace ('down' ,'up' )]
355+ newSource = source .replace ('down' ,'' )
356+ elif 'Down' in source :
357+ upHist = errorHists [source .replace ('Down' ,'Up' )]
358+ newSource = source .replace ('Down' ,'' )
359+ elif '-' in source :
360+ upHist = errorHists [source .replace ('-' ,'+' )]
361+ newSource = source .replace ('-' ,'' )
362+ elif 'lower' in source :
363+ upHist = errorHists [source .replace ('lower' ,'upper' )]
364+ newSource = source .replace ('lower' ,'' )
365+
366+ if newSource [- 1 ] == '_' :
367+ newSource = newSource [:- 1 ]
368+ # if '_' in newSource:
369+ # newSource = newSource.replace('_','')
370+
371+ symmetricErrorHists [newSource ] = []
372+ for errorup , errordown in zip (hist , upHist ):
373+ newError = max ( abs (errorup ), abs (errordown ) )
374+ symmetricErrorHists [newSource ].append (newError )
375+ elif 'TTJets_hadronisation' in source or 'QCD_shape' in source or 'TTJets_NLOgenerator' in source :
376+ symmetricErrorHists [source ] = [ abs (i ) for i in hist ]
377+
378+ x_limits = [bins [0 ], bins [- 1 ]]
379+ y_limits = [0 ,0.6 ]
380+ plt .figure ( figsize = ( 20 , 16 ), dpi = 200 , facecolor = 'white' )
381+
382+ ax0 = plt .axes ()
383+ ax0 .minorticks_on ()
384+ ax0 .xaxis .labelpad = 12
385+ ax0 .yaxis .labelpad = 12
386+ ax0 .set_xlim ( x_limits )
387+ plt .tick_params ( ** CMS .axis_label_major )
388+ plt .tick_params ( ** CMS .axis_label_minor )
389+
390+
391+ statisticalErrorHists = values_and_errors_to_hist ( errorHists ['statistical' ], [], bins )
392+ for source , hist in symmetricErrorHists .iteritems ():
393+ symmetricErrorHists [source ] = values_and_errors_to_hist ( hist , [], bins )
394+
395+ colours = ['silver' , 'r' , 'tan' , 'chartreuse' , 'cadetblue' , 'dodgerblue' , 'pink' , 'hotpink' , 'coral' , 'forestgreen' , 'cyan' , 'teal' , 'crimson' , 'darkmagenta' , 'olive' , 'slateblue' , 'deepskyblue' , 'orange' , 'r' ]
396+ for source , colour in zip ( symmetricErrorHists .keys (), colours ):
397+ hist = symmetricErrorHists [source ]
398+ hist .linewidth = 4
399+ hist .color = colour
400+ rplt .hist ( hist , stacked = False , axes = ax0 , cmap = my_cmap , vmin = 1 , label = source )
401+
402+ statisticalErrorHists .linewidth = 4
403+ statisticalErrorHists .color = 'black'
404+ statisticalErrorHists .linestyle = 'dashed'
405+ rplt .hist ( statisticalErrorHists , stacked = False , axes = ax0 , cmap = my_cmap , vmin = 1 , label = 'stat.' )
406+
407+ ax0 .set_ylim ( y_limits )
408+ leg = plt .legend (loc = 1 ,prop = {'size' :40 },ncol = 2 )
409+ leg .draw_frame (False )
410+ x_title = variables_NonLatex [variable ]
411+ if variable in ['HT' , 'MET' , 'WPT' , 'ST' , 'lepton_pt' ]:
412+ x_title += ' [GeV]'
413+ plt .xlabel ( x_title , CMS .x_axis_title )
414+ plt .ylabel ( 'Relative Uncertainty' , CMS .y_axis_title )
415+ plt .tight_layout ()
416+
417+ path = output_folder + '/' + variable + '/'
418+ make_folder_if_not_exists (path )
419+ file_template = path + '/%s_systematics_%dTeV_%s.pdf' % (variable , measurement_config .centre_of_mass_energy , channel )
420+ plt .savefig (file_template )
421+ pass
422+
325423def print_error_table (central_values , errors , channel , toFile = True , print_before_unfolding = False ):
326424 global output_folder , variable , met_type , b_tag_bin , all_measurements , phase_space
327425 bins = None
328426 bins_latex = None
427+ binEdges = None
329428 variable_latex = variables_latex [variable ]
330429 if phase_space == 'VisiblePS' :
331430 bins = variable_bins_visiblePS_ROOT [variable ]
332431 bins_latex = variable_bins_visiblePS_latex [variable ]
432+ binEdges = bin_edges_vis [variable ]
333433 elif phase_space == 'FullPS' :
334434 bins = variable_bins_ROOT [variable ]
335435 bins_latex = variable_bins_latex [variable ]
336-
436+ binEdges = bin_edges [ variable ]
337437 printout = '%% ' + '=' * 60
338438 printout += '\n '
339439 printout += '%% Systematics table for %s variable, %s channel, met type %s, %s b-tag region\n ' % (variable , channel , met_type , b_tag_bin )
@@ -367,6 +467,11 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
367467 else :
368468 assert (len (bins ) == len (central_values ['unfolded' ]))
369469
470+ errorHists = {}
471+ errorHists ['statistical' ] = []
472+ for source in all_measurements :
473+ errorHists [source ] = []
474+
370475 for bin_i , variable_bin in enumerate (bins ):
371476 header += '& %s' % (bins_latex [variable_bin ])
372477 if print_before_unfolding :
@@ -380,6 +485,9 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
380485
381486 abs_error = errors [source ][bin_i ]
382487 relative_error = getRelativeError (central_value , abs_error )
488+
489+ errorHists [source ].append (relative_error )
490+
383491 text = '%.2f' % (relative_error * 100 )
384492 if rows .has_key (source ):
385493 rows [source ].append (text )
@@ -411,9 +519,13 @@ def print_error_table(central_values, errors, channel, toFile = True, print_befo
411519 else :
412520 value , error = central_values ['unfolded' ][bin_i ]
413521 relativeError = getRelativeError (value , error )
522+ errorHists ['statistical' ].append (relativeError )
414523 total_line += ' & %.2f ' % (relativeError * 100 )
415524 printout += total_line + '\\ \\ \n '
416525
526+ if not print_before_unfolding :
527+ make_error_plot ( errorHists , binEdges )
528+
417529 #append the total systematic error to the table
418530 total_line = 'Total Sys. (\%)'
419531 for bin_i , variable_bin in enumerate (bins ):
@@ -640,6 +752,7 @@ def print_typical_systematics_table(central_values, errors, channel, toFile = Tr
640752 all_measurements .extend (rate_changing_systematics )
641753
642754 for channel in ['electron' , 'muon' , 'combined' ]:
755+ # for channel in ['combined']:
643756 normalised_xsection_measured_unfolded , normalised_xsection_measured_errors , normalised_xsection_unfolded_errors = read_xsection_measurement_results_with_errors (channel )
644757
645758 print_xsections (normalised_xsection_measured_unfolded , channel , toFile = True , print_before_unfolding = False )
0 commit comments