reco_data = readData(input_data[args[0]]['data'], tree_name, NTuple = True, observables = observables[:-1], ntupleCuts = cut, Rename = tree_name + '_' + year) # We build a mass PDF always wrt the J/psi, since there is not enough # signal to do it with. Let's hope this is OK... reco_mass_pdf = buildPdf(Components = (psi_ll, background), Observables = (mpsi,), Name='reco_mass_pdf') reco_mass_result = reco_mass_pdf.fitTo(reco_data, **fitOpts) reco_mass_result.SetName('reco_mass_result') reco_sData = SData(Pdf = reco_mass_pdf, Data = reco_data, Name = 'RecoMassSPlot') del reco_sData reco_sig_sdata = reco_sData.data(psi_ll.GetName()) reco_bkg_sdata = reco_sData.data('background') from P2VV.Reweighing import reweigh for target, source, n in [(sig_sdata_full, reco_sig_sdata, 'full_sig_sdata'), (bkg_sdata_full, reco_bkg_sdata, 'full_bkg_sdata')]: ds, weights = reweigh(target, 'nPV', source, 'nPV', binning = PV_bounds) sdatas[n] = ds else: sdatas[sub_dir + '/sig_sdata'] = sig_sdata_full sdatas[sub_dir + '/bkg_sdata'] = bkg_sdata_full sig_sdata = sig_sdata_full bkg_sdata = bkg_sdata_full elif fit_mass: if (signal_MC or prompt_MC) and options.reweigh: reco_data = readData(input_data[args[0]]['data'], tree_name, NTuple = True, observables = observables[:-1], ntupleCuts = cut, Rename = tree_name + '_' + year) reco_mass_pdf = buildPdf(Components = (psi_ll, background), Observables = (mpsi,), Name='reco_mass_pdf') reco_mass_result = reco_mass_pdf.fitTo(reco_data, **fitOpts) reco_mass_result.SetName('reco_mass_result')
def __init__(self, time, masses, t_diff = None, MassResult = None, InputFile = "/bfys/raaij/p2vv/data/Bs2JpsiPhiPrescaled_2011.root", Workspace = 'Bs2JpsiPhiPrescaled_2011_workspace', Data = 'data', UseKeysPdf = False, Weights = 'B', Draw = False, Reweigh = {}): assert(Weights in ShapeBuilder.__weights) self.__weights = Weights self.__time = time self.__t_diff = t_diff pos = Workspace.find('201') self.__year = Workspace[pos : pos + 4] self.__input_ws = None self.__ws = RooObject().ws() self.__shapes = {} self.__diff__shapes = {} self.__masses = masses self._sig = Component('wpv_signal', [], Yield = (1000, 10, 5e5)) self._psi = Component('wpv_jpsi', [], Yield = (5000, 10, 5e5)) self._bkg = Component('wpv_bkg', [], Yield = (5000, 10, 5e5)) if 'B' in masses: ## m_sig_mean = RealVar('wpv_m_sig_mean', Unit = 'MeV', Value = 5365, MinMax = (5363, 5372)) ## m_sig_sigma = RealVar('wpv_m_sig_sigma', Unit = 'MeV', Value = 10, MinMax = (1, 20)) ## from ROOT import RooGaussian as Gaussian ## self._sig_mass = Pdf(Name = 'wpv_sig_m', Type = Gaussian, Parameters = (masses['B'], m_sig_mean, m_sig_sigma )) self._sig_mass = BMassPdf(masses['B'], Name = 'wpv_sig_mass', ParNamePrefix = "wpv", AvSigParameterisation = True) self._bkg_mass = BBkgPdf(masses['B'], Name = 'wpv_bkg_mass', ParNamePrefix = "wpv", m_bkg_exp = dict(Name = 'm_bkg_exp', Value = -0.0017, MinMax = (-0.01, -0.00001))) self._sig[masses['B']] = self._sig_mass.pdf() self._psi[masses['B']] = self._bkg_mass.pdf() self._bkg[masses['B']] = self._bkg_mass.pdf() if 'jpsi' in masses: self._sig_mpsi = PsiMassPdf(masses['jpsi'], Name = 'wpv_sig_mpsi', ParNamePrefix = "wpv") self._bkg_mpsi = PsiBkgPdf(masses['jpsi'], Name = 'wpv_bkg_mpsi', ParNamePrefix = "wpv") self._sig[masses['jpsi']] = self._sig_mpsi.pdf() self._psi[masses['jpsi']] = self._sig_mpsi.pdf() self._bkg[masses['jpsi']] = self._bkg_mpsi.pdf() self.__components = {'jpsi' : dict(jpsi = self._psi, bkg = self._bkg), 'B' : dict(B = self._sig, bkg = self._bkg), 'both' : dict(B = self._sig, jpsi = self._psi, bkg = self._bkg)} self.__pdf = buildPdf(self.__components[Weights].values(), Observables = masses.values(), Name = 'wpv_mass_pdf') if MassResult: ## Use the provided mass result to set all the parameter values, only float the yields pdf_params = self.__pdf.getParameters(RooArgSet(*masses.values())) for p in MassResult.floatParsFinal(): ## ignore yields if any((p.GetName().startswith(n) for n in ['N_', 'mpsi_c'])): continue ## Find pdf parameter, add "wpv_" prefix pdf_p = pdf_params.find('wpv_' + p.GetName()) if pdf_p: pdf_p.setVal(p.getVal()) pdf_p.setError(p.getError()) pdf_p.setConstant(True) self.__pdf.Print("t") from ROOT import TFile input_file = TFile.Open(InputFile) if not input_file or not input_file.IsOpen(): raise OSError if Workspace: self.__input_ws = input_file.Get(Workspace) if not self.__input_ws: print 'Cannot find workspace %s in mixing file.' % Workspace raise RuntimeError self._data = self.__input_ws.data(Data) if not self._data: print 'Cannot find data in workspace %s.' % Workspace raise RuntimeError else: self._data = input_file.Get(Data) if not self._data.get().find(time.GetName()) and "refit" in time.GetName(): from ROOT import RooFormulaVar, RooArgList def __add_alias(name, obs): obs_name = obs.GetName()[:-6] do = self._data.get().find(obs_name) rf = RooFormulaVar(name, name, "@0", RooArgList(do)) a = self._data.addColumn(rf) a.setMin(obs.getMin()) a.setMax(obs.getMax()) return a ## Add refit observables time = __add_alias("time_refit", time) self.__time = time self.__time.Print() if t_diff: t_diff = __add_alias("time_diff_refit", t_diff) self.__t_diff = t_diff if t_diff: self._data = self._data.reduce("{0} > {1} && {0} < {2} && {3} > {4} && {3} < {5}".format(time.GetName(), time.getMin(), time.getMax(), t_diff.GetName(), t_diff.getMin(), t_diff.getMax())) else: self._data = self._data.reduce("{0} > {1} && {0} < {2}".format(time.GetName(), time.getMin(), time.getMax())) # self._data = self._data.reduce("mass > 5348 && mass < 5388") fitOpts = dict(NumCPU = 4, Save = True, Minimizer = 'Minuit2', Optimize = 2) self.__result = self.__pdf.fitTo(self._data, **fitOpts) from P2VV.Utilities.SWeights import SData for p in self.__pdf.Parameters(): p.setConstant(not p.getAttribute('Yield')) splot = SData(Pdf = self.__pdf, Data = self._data, Name = 'MixingMassSplot') self.__sdatas = {} self.__reweigh_weights = {} for key, c in self.__components[Weights].iteritems(): sdata = splot.data(c.GetName()) if 'Data' in Reweigh and key in Reweigh['Data']: from array import array from ROOT import RooBinning source = Reweigh['Data'][key] binning = Reweigh['Binning'] if type(binning) == array: binning = RooBinning(len(binning) - 1, binning) binning.SetName('reweigh') Reweigh['DataVar'].setBinning(binning, 'reweigh') source_obs = source.get().find('nPV') cat_name = 'nPVs_' + key source_cat = source.get().find(cat_name) if source_cat: # Remove previous weights to make sure we get it right new_vars = source.get() new_vars.remove(source_cat) source = source.reduce(new_vars) source_obs = source.get().find(source_obs.GetName()) source_obs.setBinning(binning, 'reweigh') source_cat = BinningCategory(Name = cat_name, Observable = source_obs, Binning = binning, Data = source, Fundamental = True) from P2VV.Reweighing import reweigh sdata, weights = reweigh(sdata, sdata.get().find('nPV'), source, source_cat) self.__reweigh_weights[key] = weights sdata = self.__ws.put(sdata) self.__sdatas[c] = sdata rho_keys = dict((v, k) for k, v in self.__components[Weights].iteritems()) self.__shapes = {} self.__diff_shapes = {} for c, sdata in self.__sdatas.iteritems(): if UseKeysPdf: rk = rho_keys[c] rho = ShapeBuilder.__rho[rk] if rk in ShapeBuilder.__rho else 1. time_shape = KeysPdf(Name = 'wpv_%s_pdf' % c.GetName(), Observable = time, Data = sdata, Rho = rho) if t_diff: diff_shape = KeysPdf(Name = 'wpv_%s_diff_pdf' % c.GetName(), Observable = t_diff, Data = sdata) else: time_shape = HistPdf(Name = 'wpv_%s_pdf' % c.GetName(), Observables = [time], Data = sdata, Binning = {time : 35}) if t_diff: diff_shape = HistPdf(Name = 'wpv_%s_diff_pdf' % c.GetName(), Observables = [t_diff], Data = sdata, Binning = {time : 35}) self.__shapes[c] = time_shape if t_diff: self.__diff_shapes[c] = diff_shape if Draw: self.__draw()
st = RealVar('sigmat',Title = '#sigma(t)', Unit = 'ps', Observable = True, MinMax = (0.01, 0.07)) # add 20 bins for caching the normalization integral for i in [ st ] : i.setBins( 20 , 'cache' ) # Categories needed for selecting events unbiased = Category('triggerDecisionUnbiasedPrescaled', States = {'unbiased' : 1, 'not_unbiased' : 0}, Observable = True) nPV = RealVar('nPV', Title = 'Number of PVs', Observable = True, MinMax = (0, 10)) zerr = RealVar('B_s0_bpv_zerr', Title = 'Best PV Z error', Unit = 'mm', Observable = True, MinMax = (0, 1)) observables = [t, m, mpsi, st, unbiased, nPV, zerr] cut = 'sel == 1 && triggerDecisionUnbiasedPrescaled == 1 && ' cut += ' && '.join(['%s < 4' % e for e in ['muplus_track_chi2ndof', 'muminus_track_chi2ndof', 'Kplus_track_chi2ndof', 'Kminus_track_chi2ndof']]) cut += ' && sel_cleantail == 1' from P2VV.GeneralUtils import readData tree_name = 'DecayTree' data = {} for s in ['2011', 'MC11a_incl_Jpsi']: ds = readData(input_data[s]['data'], tree_name, NTuple = True, observables = observables, ntupleCuts = cut, Rename = tree_name + '_' + s) ds.SetName(tree_name + '_' + s) data[s] = ds from array import array PV_bounds = array('d', [-0.5 + i for i in range(12)]) from P2VV.Reweighing import reweigh reweighed_data, weights = reweigh(data['MC11a_incl_Jpsi'], 'nPV', data['2011'], nPV, binning = PV_bounds)