@@ -65,15 +65,18 @@ def __init__(self, datap, case, typean, period):
6565 suffix = f"results.{ period } " if period is not None else "resultsallp"
6666 self .d_resultsallpmc = self .cfg (f"mc.{ suffix } " )
6767 self .d_resultsallpdata = self .cfg (f"data.{ suffix } " )
68+ self .d_resultsallpfd = self .cfg (f"fd.{ suffix } " )
6869
6970 # input directories (processor output)
7071 self .d_resultsallpdata_proc = self .cfg (f"data_proc.{ suffix } " )
7172 self .d_resultsallpmc_proc = self .cfg (f"mc_proc.{ suffix } " )
73+ self .d_resultsallpfd_proc = self .cfg (f"fd_proc.{ suffix } " )
7274
7375 # input files
7476 n_filemass_name = datap ["files_names" ]["histofilename" ]
7577 self .n_filemass = os .path .join (self .d_resultsallpdata_proc , n_filemass_name )
7678 self .n_filemass_mc = os .path .join (self .d_resultsallpmc_proc , n_filemass_name )
79+ self .n_filemass_fd = os .path .join (self .d_resultsallpfd_proc , n_filemass_name )
7780 self .n_fileeff = datap ["files_names" ]["efffilename" ]
7881 self .n_fileeff = os .path .join (self .d_resultsallpmc_proc , self .n_fileeff )
7982 self .n_fileresp = datap ["files_names" ]["respfilename" ]
@@ -83,9 +86,8 @@ def __init__(self, datap, case, typean, period):
8386 self .p_pdfnames = datap ["analysis" ][self .typean ].get ("pdf_names" )
8487 self .p_param_names = datap ["analysis" ][self .typean ].get ("param_names" )
8588
86- # TODO: should come entirely from DB
8789 self .observables = {
88- "qa" : ["zg " , "rg" , "nsd" , "zpar" , "dr" , "lntheta" , "lnkt" , "lntheta-lnkt" ],
90+ "qa" : [* self . cfg ( "observables " , {}) ],
8991 "all" : [* self .cfg ("observables" , {})],
9092 }
9193
@@ -114,7 +116,7 @@ def __init__(self, datap, case, typean, period):
114116 for param , symbol in zip (
115117 ("mean" , "sigma" , "significance" , "chi2" ),
116118 ("#it{#mu}" , "#it{#sigma}" , "significance" , "#it{#chi}^{2}" ),
117- strict = False ,
119+ strict = True ,
118120 )
119121 }
120122 for level in self .fit_levels
@@ -209,7 +211,7 @@ def qa(self): # pylint: disable=invalid-name
209211 # region efficiency
210212 # pylint: disable=too-many-statements
211213 def calculate_efficiencies (self ):
212- self .logger .info ("Calculating efficiencies" )
214+ self .logger .info ("Calculating efficiencies from %s" , self . n_fileeff )
213215 cats = {"pr" , "np" }
214216 with TFile (self .n_fileeff ) as rfile :
215217 h_gen = {cat : rfile .Get (f"h_ptjet-pthf_{ cat } _gen" ) for cat in cats }
@@ -586,9 +588,6 @@ def fit(self):
586588 if iptjet is None :
587589 if not fitcfg .get ("per_ptjet" ):
588590 for jptjet in range (get_nbins (h , 1 )):
589- self .logger .info (
590- "Overwriting roows_ptjet for %s iptjet %s ipt %d" , level , jptjet , ipt
591- )
592591 self .roows [(jptjet , ipt )] = roo_ws .Clone ()
593592 self .roo_ws [(level , jptjet , ipt )] = roo_ws .Clone ()
594593 if level in ("data" , "mc" ):
@@ -685,7 +684,6 @@ def _subtract_sideband(self, hist, var, mcordata, ipt):
685684 # project out the mass regions (first axis)
686685 axes = list (range (get_dim (hist )))[1 :]
687686 fh [region ] = project_hist (hist , axes , {0 : bins [region ]})
688- self .logger .info ("Projecting %s to %s in %s: %g entries" , hist , axes , bins [region ], fh [region ].GetEntries ())
689687 self ._save_hist (
690688 fh [region ], f"sideband/h_ptjet{ label } _{ region } _{ string_range_pthf (range_pthf )} _{ mcordata } .png"
691689 )
@@ -702,11 +700,8 @@ def _subtract_sideband(self, hist, var, mcordata, ipt):
702700 self .logger .info ("Scaling sidebands in ptjet-%s bins: %s using %s" , label , bins_ptjet , fh_sideband )
703701 hx = project_hist (fh_sideband , (0 ,), {}) if get_dim (fh_sideband ) > 1 else fh_sideband
704702 for iptjet in bins_ptjet :
705- if iptjet :
706- n = hx .GetBinContent (iptjet )
707- self .logger .info ("Need to scale in ptjet %i: %g" , iptjet , n )
708- if n <= 0 :
709- continue
703+ if iptjet and hx .GetBinContent (iptjet ) <= 0 :
704+ continue
710705 rws = self .roo_ws .get ((mcordata , iptjet , ipt ))
711706 if not rws :
712707 self .logger .error ("Falling back to incl. roows for %s-iptjet%i-ipt%i" , mcordata , iptjet , ipt )
@@ -1063,57 +1058,77 @@ def _extract_signal(self, hist, var, mcordata, ipt):
10631058 # hres.Sumw2() # TODO: check if we should do this here
10641059 return hres
10651060
1066- # region feeddown
1067- # pylint: disable=too-many-statements
10681061 def estimate_feeddown (self ):
1069- self .logger .info ("Estimating feeddown" )
1062+ """Estimate feeddown from legacy Run 2 trees or gen-only simulation"""
1063+ match self .cfg ("fd_input" , "tree" ):
1064+ case "tree" :
1065+ self .logger .info ("Reading feeddown information from trees" )
1066+ with TFile (self .cfg ("fd_root" )) as rfile :
1067+ powheg_xsection = rfile .Get ("fHistXsection" )
1068+ powheg_xsection_scale_factor = powheg_xsection .GetBinContent (1 ) / powheg_xsection .GetEntries ()
1069+ self .logger .info ("POWHEG luminosity (mb^{-1}): %g" , 1.0 / powheg_xsection_scale_factor )
1070+
1071+ df = pd .read_parquet (self .cfg ("fd_parquet" ))
1072+ col_mapping = {"dr" : "delta_r_jet" , "zpar" : "z" } # TODO: check mapping
1073+
1074+ # TODO: generalize to higher dimensions
1075+ h3_fd_gen_orig = {}
1076+ for var in self .observables ["all" ]:
1077+ bins_ptjet = np .asarray (self .cfg ("bins_ptjet" ), "d" )
1078+ # TODO: generalize or derive from histogram?
1079+ bins_obs = {}
1080+ if binning := self .cfg (f"observables.{ var } .bins_gen_var" ):
1081+ bins_tmp = np .asarray (binning , "d" )
1082+ elif binning := self .cfg (f"observables.{ var } .bins_gen_fix" ):
1083+ bins_tmp = bin_array (* binning )
1084+ elif binning := self .cfg (f"observables.{ var } .bins_var" ):
1085+ bins_tmp = np .asarray (binning , "d" )
1086+ elif binning := self .cfg (f"observables.{ var } .bins_fix" ):
1087+ bins_tmp = bin_array (* binning )
1088+ else :
1089+ self .logger .error ("no binning specified for %s, using defaults" , var )
1090+ bins_tmp = bin_array (10 , 0.0 , 1.0 )
1091+ bins_obs [var ] = bins_tmp
10701092
1071- with TFile (self .cfg ("fd_root" )) as rfile :
1072- powheg_xsection = rfile .Get ("fHistXsection" )
1073- powheg_xsection_scale_factor = powheg_xsection .GetBinContent (1 ) / powheg_xsection .GetEntries ()
1074- self .logger .info ("POWHEG luminosity (mb^{-1}): %g" , 1.0 / powheg_xsection_scale_factor )
1093+ colname = col_mapping .get (var , f"{ var } _jet" )
1094+ if f"{ colname } " not in df :
1095+ if var is not None :
1096+ self .logger .error (
1097+ "No feeddown information for %s (%s), cannot estimate feeddown" , var , colname
1098+ )
1099+ # print(df.info(), flush=True)
1100+ continue
10751101
1076- df = pd .read_parquet (self .cfg ("fd_parquet" ))
1077- col_mapping = {"dr" : "delta_r_jet" , "zpar" : "z" } # TODO: check mapping
1102+ # TODO: derive histogram
1103+ h3_fd_gen_orig [var ] = create_hist (
1104+ "h3_feeddown_gen" ,
1105+ f";p_{{T}}^{{jet}} (GeV/#it{{c}});p_{{T}}^{{HF}} (GeV/#it{{c}});{ var } " ,
1106+ bins_ptjet ,
1107+ self .bins_candpt ,
1108+ bins_obs [var ],
1109+ )
1110+ fill_hist_fast (h3_fd_gen_orig [var ], df [["pt_jet" , "pt_cand" , f"{ colname } " ]])
1111+
1112+ case "sim" :
1113+ h3_fd_gen_orig = {}
1114+ with TFile (self .n_filemass_fd ) as rfile :
1115+ for var in self .observables ["all" ]:
1116+ self .logger .info ("Running feeddown analysis for obs. %s" , var )
1117+ label = f"-{ var } " if var else ""
1118+ if fh := rfile .Get (f"h_mass-ptjet-pthf{ label } " ):
1119+ h3_fd_gen_orig [var ] = project_hist (fh , list (range (1 , get_dim (fh ))), {})
1120+ h_norm = rfile .Get ("histonorm" )
1121+ powheg_xsection_avg = h_norm .GetBinContent (6 ) / h_norm .GetBinContent (5 )
1122+ powheg_xsection_scale_factor = powheg_xsection_avg / h_norm .GetBinContent (5 )
1123+ self .logger .info ("powheg_xsection_scale_factor = %f" , powheg_xsection_scale_factor )
1124+ self .logger .info ("POWHEG luminosity (mb^{-1}): %g" , 1. / powheg_xsection_scale_factor )
1125+
1126+ case fd_input :
1127+ self .logger .critical ("Invalid feeddown input %s" , fd_input )
10781128
1079- # TODO: generalize to higher dimensions
10801129 for var in self .observables ["all" ]:
1081- bins_ptjet = np .asarray (self .cfg ("bins_ptjet" ), "d" )
1082- # TODO: generalize or derive from histogram?
1083- bins_obs = {}
1084- if binning := self .cfg (f"observables.{ var } .bins_gen_var" ):
1085- bins_tmp = np .asarray (binning , "d" )
1086- elif binning := self .cfg (f"observables.{ var } .bins_gen_fix" ):
1087- bins_tmp = bin_array (* binning )
1088- elif binning := self .cfg (f"observables.{ var } .bins_var" ):
1089- bins_tmp = np .asarray (binning , "d" )
1090- elif binning := self .cfg (f"observables.{ var } .bins_fix" ):
1091- bins_tmp = bin_array (* binning )
1092- else :
1093- self .logger .error ("no binning specified for %s, using defaults" , var )
1094- bins_tmp = bin_array (10 , 0.0 , 1.0 )
1095- bins_obs [var ] = bins_tmp
1096-
1097- colname = col_mapping .get (var , f"{ var } _jet" )
1098- if f"{ colname } " not in df :
1099- if var is not None :
1100- self .logger .error ("No feeddown information for %s (%s), cannot estimate feeddown" , var , colname )
1101- # print(df.info(), flush=True)
1102- continue
1103-
1104- # TODO: derive histogram
1105- h3_fd_gen_orig = create_hist (
1106- "h3_feeddown_gen" ,
1107- f";p_{{T}}^{{jet}} (GeV/#it{{c}});p_{{T}}^{{HF}} (GeV/#it{{c}});{ var } " ,
1108- bins_ptjet ,
1109- self .bins_candpt ,
1110- bins_obs [var ],
1111- )
1112- fill_hist_fast (h3_fd_gen_orig , df [["pt_jet" , "pt_cand" , f"{ colname } " ]])
1113- self ._save_hist (project_hist (h3_fd_gen_orig , [0 , 2 ], {}), f"fd/h_ptjet-{ var } _feeddown_gen_noeffscaling.png" )
1114-
11151130 # new method
1116- h3_fd_gen = h3_fd_gen_orig .Clone ()
1131+ h3_fd_gen = h3_fd_gen_orig [ var ] .Clone ()
11171132 ensure_sumw2 (h3_fd_gen )
11181133 self ._save_hist (project_hist (h3_fd_gen , [0 , 2 ], {}), f"fd/h_ptjet-{ var } _fdnew_gen.png" )
11191134 # apply np efficiency
@@ -1158,7 +1173,7 @@ def estimate_feeddown(self):
11581173 h_fd_det = project_hist (h3_fd_det , [0 , 2 ], {})
11591174
11601175 # old method
1161- h3_fd_gen = h3_fd_gen_orig .Clone ()
1176+ h3_fd_gen = h3_fd_gen_orig [ var ] .Clone ()
11621177 ensure_sumw2 (h3_fd_gen )
11631178 for ipt in range (get_nbins (h3_fd_gen , 1 )):
11641179 eff_pr = self .hcandeff ["pr" ].GetBinContent (ipt + 1 )
0 commit comments