11from __future__ import annotations
22
33import argparse
4- from glob import glob
54from collections import defaultdict
5+ from datetime import datetime
6+ from glob import glob
67
78import matplotlib .pyplot as plt
89import mplhep as hep # type: ignore
1112def parser_setup () -> argparse .ArgumentParser :
1213 parser = argparse .ArgumentParser (prog = "plotting_script.py" , description = "Plotting script" )
1314 parser .add_argument ("--input" , "-i" , type = str , help = "Input Folder; defaults to './'" , default = "./" )
14- parser .add_argument ("--output" , "-o" , type = str , help = "Output file with extension; defaults to './output .png'" , default = "./output.png" )
15+ parser .add_argument ("--output" , "-o" , type = str , help = "Output file with extension; defaults to './*current date* .png'" , default = None )
1516 parser .add_argument (
16- "--channel" , "-c" , type = str , nargs = "*" , choices = ["Higgs" , "W" , "Z" , "all" ], default = [ "Higgs" , "Z" ] ,
17- help = "Channel to plot; default plots all channels." ,
17+ "--channel" , "-c" , type = str , nargs = "*" , choices = ["Higgs" , "W" , "Z" , "all" ], default = None ,
18+ help = "Channel(s) to plot; defaults to Higgs and Z channels." ,
1819 )
1920 parser .add_argument ("--min" , "-m" , type = float , default = 10.0 , help = "minimum value for the histogram; default is 10.0" )
2021 parser .add_argument ("--unstack" , "-u" , action = 'store_true' , default = False , help = "Unstack the histograms; default is stacked" )
@@ -23,8 +24,13 @@ def parser_setup() -> argparse.ArgumentParser:
2324 return parser
2425
2526
26- def get_files_by_channel (channel : str , input_folder : str ) -> dict [str , list [str ]]:
27- channels = ["Higgs" , "W" , "Z" ] if channel == "all" else [channel ]
27+ def get_files_by_channel (channel : str | list [str ] | None , input_folder : str ) -> dict [str , list [str ]]:
28+ if not channel :
29+ channels = ["Higgs" , "Z" ]
30+ elif channel == "all" :
31+ channels = ["Higgs" , "W" , "Z" ]
32+ else :
33+ channels = channel if isinstance (channel , list ) else [channel ]
2834 if "W" in channels :
2935 channels .extend (["Wp" , "Wm" ])
3036 channels .remove ("W" )
@@ -89,16 +95,18 @@ def _read_file(self, file: str) -> list[float]:
8995 def w_ratio (self ):
9096 """ Calculates the ratio of W+ to W- events.
9197 """
92- wp = self .data ["Wp" ]
93- wm = self .data ["Wm" ]
98+ wp = len ( self .data ["Wp" ])
99+ wm = len ( self .data ["Wm" ])
94100
95101 print (40 * "*" )
96102 print ("***\t Calculating W+ to W- ratio..." )
97- if len ( wm ) == 0 :
103+ if wm == 0 :
98104 print ("!!!\t No W- events found. Skipping W+ to W- ratio calculation." )
99105 else :
100- print (f"***\t Found: { len (wp )} W+ events and { len (wm )} W- events." )
101- print (f"***\t W+ to W- ratio: { len (wp ) / len (wm )} " )
106+ w_ratio = wp / wm
107+ w_error = np .sqrt (w_ratio / wm * (1 + w_ratio ))
108+ print (f"***\t Found: { wp } W+ events and { wm } W- events." )
109+ print (f"***\t W+ to W- ratio: { w_ratio } ± { w_error } (stat)" )
102110 print (40 * "*" )
103111
104112 def items (self ) -> tuple [list [str ], list [list [float ]]]:
@@ -151,6 +159,8 @@ def plot_masses(reader: MassReader, unstack: bool, output: str, **kwargs):
151159def main ():
152160 parser = parser_setup ()
153161 args = parser .parse_args ()
162+ if args .output is None :
163+ args .output = f"./{ datetime .now ().strftime ('%d%m%Y' )} .png"
154164 files = get_files_by_channel (args .channel , args .input )
155165 if not files :
156166 raise Exception (f"No files found for channel '{ args .channel } ' in folder '{ args .input } '" )
0 commit comments