13 from __future__
import print_function
14 from builtins
import range
24 from matplotlib
import pyplot
as plt
28 from RecoLuminosity.LumiDB.mpl_axes_hist_fix
import hist
29 if matplotlib.__version__ !=
'1.0.1':
30 print(
"ERROR The %s script contains a hard-coded bug-fix " \
31 "for Matplotlib 1.0.1. The Matplotlib version loaded " \
32 "is %s" % (__file__, matplotlib.__version__), file=sys.stderr)
34 matplotlib.axes.Axes.hist = hist
37 from ROOT
import gROOT
39 from ROOT
import PyConfig
40 PyConfig.IgnoreCommandLineOptions =
True 41 from ROOT
import TFile
43 from RecoLuminosity.LumiDB.public_plots_tools
import ColorScheme
44 from RecoLuminosity.LumiDB.public_plots_tools
import LatexifyUnits
45 from RecoLuminosity.LumiDB.public_plots_tools
import AddLogo
46 from RecoLuminosity.LumiDB.public_plots_tools
import InitMatplotlib
47 from RecoLuminosity.LumiDB.public_plots_tools
import RoundAwayFromZero
48 from RecoLuminosity.LumiDB.public_plots_tools
import SavePlot
49 from RecoLuminosity.LumiDB.public_plots_tools
import FONT_PROPS_SUPTITLE
50 from RecoLuminosity.LumiDB.public_plots_tools
import FONT_PROPS_TITLE
51 from RecoLuminosity.LumiDB.public_plots_tools
import FONT_PROPS_AX_TITLE
52 from RecoLuminosity.LumiDB.public_plots_tools
import FONT_PROPS_TICK_LABEL
66 ax.autoscale_view(
False,
True,
True)
67 for label
in ax.get_xticklabels():
69 label.set_rotation(30.)
73 if add_extra_head_room:
74 y_ticks = ax.get_yticks()
75 (y_min, y_max) = ax.get_ylim()
76 is_log = (ax.get_yscale() ==
"log")
79 tmp = y_ticks[-1] / y_ticks[-2]
80 y_max_new = y_max * math.pow(tmp, add_extra_head_room)
82 tmp = y_ticks[-1] - y_ticks[-2]
83 y_max_new = y_max + add_extra_head_room * tmp
84 ax.set_ylim(y_min, y_max_new)
88 ax_sec.set_ylim(ax.get_ylim())
89 ax_sec.set_yscale(ax.get_yscale())
91 for ax_tmp
in fig.axes:
92 for sub_ax
in [ax_tmp.xaxis, ax_tmp.yaxis]:
93 for label
in sub_ax.get_ticklabels():
94 label.set_font_properties(FONT_PROPS_TICK_LABEL)
97 fig.subplots_adjust(top=.89, bottom=.125, left=.11, right=.925)
99 fig.subplots_adjust(top=.89, bottom=.125, left=.1, right=.925)
105 if __name__ ==
"__main__":
107 desc_str =
"This script creates the official CMS pileup plots " \
108 "based on the output from the pileupCalc.py script." 109 arg_parser = optparse.OptionParser(description=desc_str)
110 arg_parser.add_option(
"--ignore-cache", action=
"store_true",
111 help=
"Ignore all cached PU results " \
112 "and run pileupCalc. " \
113 "(Rebuilds the cache as well.)")
114 (options, args) = arg_parser.parse_args()
116 print(
"ERROR Need exactly one argument: a config file name", file=sys.stderr)
118 config_file_name = args[0]
119 ignore_cache = options.ignore_cache
122 "pileupcalc_flags" :
"",
123 "color_schemes" :
"Joe, Greg",
126 cfg_parser = ConfigParser.SafeConfigParser(cfg_defaults)
127 if not os.path.exists(config_file_name):
128 print(
"ERROR Config file '%s' does not exist" % config_file_name, file=sys.stderr)
130 cfg_parser.read(config_file_name)
133 cache_file_dir = cfg_parser.get(
"general",
"cache_dir")
136 color_scheme_names_tmp = cfg_parser.get(
"general",
"color_schemes")
137 color_scheme_names = [i.strip()
for i
in color_scheme_names_tmp.split(
",")]
139 verbose = cfg_parser.getboolean(
"general",
"verbose")
142 pileupcalc_flags_from_cfg = cfg_parser.get(
"general",
"pileupcalc_flags")
143 input_json = cfg_parser.get(
"general",
"input_json")
144 input_lumi_json = cfg_parser.get(
"general",
"input_lumi_json")
147 particle_type_str = cfg_parser.get(
"general",
"particle_type_str")
148 year =
int(cfg_parser.get(
"general",
"year"))
149 cms_energy_str = cfg_parser.get(
"general",
"cms_energy_str")
154 print(
"Using configuration from file '%s'" % config_file_name)
155 print(
"Using color schemes '%s'" %
", ".
join(color_scheme_names))
156 print(
"Using additional pileupCalc flags from configuration: '%s'" % \
157 pileupcalc_flags_from_cfg)
158 print(
"Using input JSON filter: %s" % input_json)
159 print(
"Using input lumi JSON filter: %s" % input_lumi_json)
168 tmp_file_name = os.path.join(cache_file_dir,
"pileup_calc_tmp.root")
170 cmd =
"pileupCalc.py -i %s --inputLumiJSON=%s %s %s" % \
171 (input_json, input_lumi_json,
172 pileupcalc_flags_from_cfg, tmp_file_name)
173 print(
"Running pileupCalc (this may take a while)")
175 print(
" pileupCalc cmd: '%s'" % cmd)
176 (status, output) = commands.getstatusoutput(cmd)
178 print(
"ERROR Problem running pileupCalc: %s" % output, file=sys.stderr)
183 in_file = TFile.Open(tmp_file_name,
"READ")
184 if not in_file
or in_file.IsZombie():
185 print(
"ERROR Could not read back pileupCalc results", file=sys.stderr)
187 pileup_hist = in_file.Get(
"pileup")
188 pileup_hist.SetDirectory(0)
194 print(
"Drawing things...")
195 ColorScheme.InitColors()
198 bin_edges = [pileup_hist.GetBinLowEdge(i) \
199 for i
in range(1, pileup_hist.GetNbinsX() + 1)]
200 vals = [pileup_hist.GetBinCenter(i) \
201 for i
in range(1, pileup_hist.GetNbinsX() + 1)]
202 weights = [pileup_hist.GetBinContent(i) \
203 for i
in range(1, pileup_hist.GetNbinsX() + 1)]
205 weights = [1.e-6 * i
for i
in weights]
208 for color_scheme_name
in color_scheme_names:
210 print(
" color scheme '%s'" % color_scheme_name)
212 color_scheme = ColorScheme(color_scheme_name)
213 color_line_pileup = color_scheme.color_line_pileup
214 color_fill_pileup = color_scheme.color_fill_pileup
215 logo_name = color_scheme.logo_name
216 file_suffix = color_scheme.file_suffix
220 for type
in [
"lin",
"log"]:
221 is_log = (type ==
"log")
226 log_setting = math.pow(10., exp)
229 ax = fig.add_subplot(111)
231 ax.hist(vals, bins=bin_edges, weights=weights, log=log_setting,
232 histtype=
"stepfilled",
233 edgecolor=color_line_pileup,
234 facecolor=color_fill_pileup)
237 fig.suptitle(
r"CMS Average Pileup, " \
238 "%s, %d, $\mathbf{\sqrt{s} =}$ %s" % \
239 (particle_type_str, year, cms_energy_str),
240 fontproperties=FONT_PROPS_SUPTITLE)
241 ax.set_xlabel(
r"Mean number of interactions per crossing",
242 fontproperties=FONT_PROPS_AX_TITLE)
243 ax.set_ylabel(
r"Recorded Luminosity (%s/%.2f)" % \
245 pileup_hist.GetBinWidth(1)),
246 fontproperties=FONT_PROPS_AX_TITLE)
249 ax.text(.95, .925,
r"<$\mathbf{\mu}$> = %.0f" % \
250 round(pileup_hist.GetMean()),
251 transform = ax.transAxes,
252 horizontalalignment=
"right",
253 fontproperties=FONT_PROPS_AX_TITLE)
262 SavePlot(fig,
"pileup_%s_%d%s%s" % \
263 (particle_type_str, year,
264 log_suffix, file_suffix))
S & print(S &os, JobReport::InputFile const &f)
def TweakPlot(fig, ax, add_extra_head_room=False)
static std::string join(char **cmd)