def latexfitresults_method2(filename, resultname='RooExpandedFitResult_afterFit', region='3jL', sample='', fitregions='WR,TR,S3,S4,SR3jT,SR4jT', dataname='obsData'): # namemap = {} # namemap = getnamemap() ############################################ w = Util.GetWorkspaceFromFile(filename, 'w') if w == None: print "ERROR : Cannot open workspace : " sys.exit(1) result = w.obj(resultname) if result == None: print "ERROR : Cannot open fit result : ", resultname sys.exit(1) resultlistOrig = result.floatParsFinal() snapshot = 'snapshot_paramsVals_' + resultname w.loadSnapshot(snapshot) data_set = w.data(dataname) if data_set == None: print "ERROR : Cannot open dataset : ", "data_set" sys.exit(1) regionCat = w.obj("channelCat") data_set.table(regionCat).Print("v") regionFullName = Util.GetFullRegionName(regionCat, region) fitRegionsList = fitregions.split(",") fitRegionsFullName = "" for reg in fitRegionsList: regFullName = Util.GetFullRegionName(regionCat, reg) if fitRegionsFullName == "": fitRegionsFullName = regFullName.Data() else: fitRegionsFullName = fitRegionsFullName + "," + regFullName.Data() chosenSample = False if sample is not '': chosenSample = True ##################################################### regSys = {} regionCatStr = 'channelCat==channelCat::' + regionFullName.Data() dataRegion = data_set.reduce(regionCatStr) nobsRegion = 0. if dataRegion: nobsRegion = dataRegion.sumEntries() else: print " ERROR : dataset-category", regionCatStr, " not found" if chosenSample: regSys['sqrtnobsa'] = 0. else: regSys['sqrtnobsa'] = TMath.Sqrt(nobsRegion) #### if chosenSample: pdfInRegion = Util.GetComponent(w, sample, region) else: rawPdfInRegion = Util.GetRegionPdf(w, region) varInRegion = Util.GetRegionVar(w, region) prodList = rawPdfInRegion.pdfList() foundRRS = 0 for idx in range(prodList.getSize()): if prodList[idx].InheritsFrom("RooRealSumPdf"): rrspdfInt = prodList[idx].createIntegral( RooArgSet(varInRegion)) pdfInRegion = rrspdfInt foundRRS += 1 if foundRRS > 1 or foundRRS == 0: print " \n\n WARNING: ", pdf.GetName( ), " has ", foundRRS, " instances of RooRealSumPdf" print pdf.GetName(), " component list:", prodList.Print("v") if not pdfInRegion: if chosenSample: print " \n Warning, could not find pdf in region = ", region, " for sample = ", sample else: print " \n Warning, could not find pdf in region = ", region nFittedInRegion = pdfInRegion.getVal() regSys['sqrtnfitted'] = TMath.Sqrt(nFittedInRegion) pdfFittedErrInRegion = Util.GetPropagatedError(pdfInRegion, result) regSys['totsyserr'] = pdfFittedErrInRegion # redo the fit for every parameter being fixed lumiConst = True fpf = result.floatParsFinal() # redo the fit for every parameter being fixed for idx in range(fpf.getSize()): parname = fpf[idx].GetName() print "\n Method-2: redoing fit with fixed parameter ", parname # the parameter that is fixed, needs to have the value of the default fit w.loadSnapshot(snapshot) par = w.var(parname) # # before redoing the fit, set the values of parameters to initial snapshot, otherwise MIGRAD cannot find improvement # w.loadSnapshot('snapshot_paramsVals_initial') # par.setVal(parDefVal) par.setConstant(True) suffix = parname + "Fixed" result_1parfixed = Util.FitPdf(w, fitRegionsFullName, lumiConst, data_set, suffix) expResultAfter_1parfixed = RooExpandedFitResult( result_1parfixed, resultlistOrig) nFittedInRegion_1parfixed = pdfInRegion.getVal() pdfFittedErrInRegion_1parfixed = Util.GetPropagatedError( pdfInRegion, expResultAfter_1parfixed) # result_1parfixed) if pdfFittedErrInRegion_1parfixed > pdfFittedErrInRegion: print "\n\n WARNING parameter ", parname, " gives a larger error when set constant. Do you expect this?" print " WARNING pdfFittedErrInRegion = ", pdfFittedErrInRegion, " pdfFittedErrInRegion_1parfixed = ", pdfFittedErrInRegion_1parfixed systError = TMath.Sqrt( abs(pdfFittedErrInRegion * pdfFittedErrInRegion - pdfFittedErrInRegion_1parfixed * pdfFittedErrInRegion_1parfixed)) par.setConstant(False) if result_1parfixed.status() == 0 and result_1parfixed.covQual( ) == 3: #and result_1parfixed.numStatusHistory()==2 and result_1parfixed.statusCodeHistory(0)==0 and result_1parfixed.statusCodeHistory(1) ==0: systError = systError else: systError = 0.0 print " WARNING : for parameter ", parname, " fixed the fit does not converge, as status=", result_1parfixed.status( ), "(converged=0), and covariance matrix quality=", result_1parfixed.covQual( ), " (full accurate==3)" print " WARNING: setting systError = 0 for parameter ", parname #if namemap.has_key(parname): # parname = namemap[parname] regSys['syserr_' + parname] = systError return regSys
def GenerateFitAndPlot(tl): from ROOT import Util from ROOT import RooExpandedFitResult print "\n***GenerateFitAndPlot for TopLevelXML %s***\n"%tl.name w = Util.GetWorkspaceFromFile(tl.wsFileName,"combined") Util.SaveInitialSnapshot(w) # Util.ReadWorkspace(w, tl.wsFileName,"combined") plotChannels = "" for reg in tl.validationChannels: if len(plotChannels)>0: plotChannels+="," pass plotChannels+=reg plotChannels = "ALL" fitChannels = "" for reg in tl.bkgConstrainChannels: if len(fitChannels)>0: fitChannels+="," pass fitChannels+=reg pass fitChannelsCR = fitChannels for reg in tl.signalChannels: if len(fitChannels)>0: fitChannels+="," pass fitChannels+=reg #fitChannels = "ALL" lumiConst = not tl.signalSample # fit toy MC if specified. When left None, data is fit by default toyMC = None if configMgr.toySeedSet and not configMgr.useAsimovSet: # generate a toy dataset print "INFO : generating toy MC set for fitting and plotting. Seed = %i" % configMgr.toySeed RooRandom.randomGenerator().SetSeed( configMgr.toySeed ) toyMC = Util.GetToyMC() # this generates one toy dataset pass elif configMgr.useAsimovSet and not configMgr.toySeedSet: # print "INFO : using Asimov set for fitting and plotting." toyMC = Util.GetAsimovSet(w) # this returns the asimov set pass else: print "INFO : using data for fitting and plotting." ## MB : turn on all JES bins. Some are turned off by HistFactory by default if True: if w.var("gamma_J3_bin_0")!=None: w.var("gamma_J3_bin_0").setConstant(False) if w.var("gamma_J3_bin_1")!=None: w.var("gamma_J3_bin_1").setConstant(False) if w.var("gamma_J3_bin_2")!=None: w.var("gamma_J3_bin_2").setConstant(False) if w.var("gamma_J3_bin_3")!=None: w.var("gamma_J3_bin_3").setConstant(False) if w.var("gamma_J3_bin_4")!=None: w.var("gamma_J3_bin_4").setConstant(False) if w.var("gamma_J3_bin_5")!=None: w.var("gamma_J3_bin_5").setConstant(False) #if w.var("gamma_J4_bin_0")!=None: w.var("gamma_J4_bin_0").setConstant(False) #if w.var("gamma_J4_bin_1")!=None: w.var("gamma_J4_bin_1").setConstant(False) if w.var("gamma_J4_bin_2")!=None: w.var("gamma_J4_bin_2").setConstant(False) if w.var("gamma_J4_bin_3")!=None: w.var("gamma_J4_bin_3").setConstant(False) if w.var("gamma_J4_bin_4")!=None: w.var("gamma_J4_bin_4").setConstant(False) if w.var("gamma_J4_bin_5")!=None: w.var("gamma_J4_bin_5").setConstant(False) if w.var("gamma_JC_bin_0")!=None: w.var("gamma_JC_bin_0").setConstant(False) if w.var("gamma_JC_bin_1")!=None: w.var("gamma_JC_bin_1").setConstant(False) if w.var("gamma_JC_bin_2")!=None: w.var("gamma_JC_bin_2").setConstant(False) if w.var("gamma_JC_bin_3")!=None: w.var("gamma_JC_bin_3").setConstant(False) if w.var("gamma_JC_bin_4")!=None: w.var("gamma_JC_bin_4").setConstant(False) if w.var("gamma_JC_bin_5")!=None: w.var("gamma_JC_bin_5").setConstant(False) if w.var("gamma_JC_bin_6")!=None: w.var("gamma_JC_bin_6").setConstant(False) # Soft lepton # if w.var("gamma_JSS_bin_0")!=None: w.var("gamma_JSS_bin_0").setConstant(False) # set Errors of all parameters to 'natural' values before plotting/fitting Util.resetAllErrors(w) mu_Top = w.var("mu_Top") print "mu_Top: " print mu_Top if mu_Top: mu_Top.setError(0.001) else: mu_Top = w.var("mu_Top_Np0") if mu_Top: mu_Top.setError(0.001) mu_Top = w.var("mu_Top_Np1") if mu_Top: mu_Top.setError(0.001) mu_Top = w.var("mu_Top_Np2") if mu_Top: mu_Top.setError(0.001) mu_Top = w.var("mu_Top_Np3") if mu_Top: mu_Top.setError(0.001) mu_Top = w.var("mu_Top_Np4") if mu_Top: mu_Top.setError(0.001) mu_Top = w.var("mu_Top_Np5") if mu_Top: mu_Top.setError(0.001) mu_WZ = w.var("mu_WZ") mu_WZpT0GeV = w.var("mu_WZpT0GeV") if mu_WZ: mu_WZ.setError(0.001) elif mu_WZpT0GeV: mu_WZpT0GeV = w.var("mu_WZpT0GeV") mu_WZpT0GeV.setError(0.001) mu_WZpT0GeV = w.var("mu_WZpT50GeV") mu_WZpT0GeV.setError(0.001) mu_WZpT0GeV = w.var("mu_WZpT100GeV") mu_WZpT0GeV.setError(0.001) mu_WZpT0GeV = w.var("mu_WZpT150GeV") mu_WZpT0GeV.setError(0.001) mu_WZpT0GeV = w.var("mu_WZpT200GeV") mu_WZpT0GeV.setError(0.001) mu_WZpT0GeV = w.var("mu_WZpT250GeV") mu_WZpT0GeV.setError(0.001) else: mu_WZ = w.var("mu_WZ_Np0") mu_WZ.setError(0.001) mu_WZ = w.var("mu_WZ_Np1") mu_WZ.setError(0.001) mu_WZ = w.var("mu_WZ_Np2") mu_WZ.setError(0.001) mu_WZ = w.var("mu_WZ_Np3") mu_WZ.setError(0.001) mu_WZ = w.var("mu_WZ_Np4") mu_WZ.setError(0.001) mu_WZ = w.var("mu_WZ_Np5") mu_WZ.setError(0.001) # set the flag for plotting ratio or pull distribution under the plot plotRatio = True # plotRatio = False means that a pull distribution will be drawn # get a list of all floating parameters for all regions simPdf = w.pdf("simPdf"); mc = Util.GetModelConfig(w) obsSet = mc.GetObservables() floatPars = Util.getFloatParList(simPdf, obsSet) # create an RooExpandedFitResult encompassing all the regions/parameters & save it to workspace expResultBefore = RooExpandedFitResult(floatPars) # expResultBefore.Print() Util.ImportInWorkspace(w,expResultBefore,"RooExpandedFitResult_beforeFit") # plot before fit #Util.PlotPdfWithComponents(w,tl.name,plotChannels,"beforeFit_ORIGINAL",None,toyMC) Util.PlotPdfWithComponents(w,tl.name,plotChannels,"beforeFit",expResultBefore,toyMC,plotRatio) #return # fit of CRs only # resultCR = Util.FitPdf(w,fitChannelsCR,lumiConst,toyMC) # load original snapshot # w.loadSnapshot('snapshot_paramsVals_initial') # fit of all regions result = Util.FitPdf(w,fitChannels,lumiConst,toyMC) # create an RooExpandedFitResult encompassing all the regions/parameters with the result & save it to workspace expResultAfter = RooExpandedFitResult(result, floatPars) Util.ImportInWorkspace(w,expResultAfter,"RooExpandedFitResult_afterFit") # plot after fit #Util.PlotPdfWithComponents(w,tl.name,plotChannels,"afterFit_ORIGINAL",result,toyMC) Util.PlotPdfWithComponents(w,tl.name,plotChannels,"afterFit",expResultAfter,toyMC,plotRatio) # plot each component of each region separately with propagated error after fit (interesting for debugging) # Util.PlotSeparateComponents(tl.name,plotChannels,"afterFit",result,toyMC) # plot correlation matrix for result #Util.PlotCorrelationMatrix(result) # Util.GetCorrelations(result, 0.85) # plotPLL = False # Util.PlotNLL(w, result, plotPLL, "", toyMC) if toyMC: Util.WriteWorkspace(w, tl.wsFileName,toyMC.GetName()) else: Util.WriteWorkspace(w, tl.wsFileName) try: if not result == None: result.Print() return result except: pass return
def latexfitresults_method2(filename, resultname='RooExpandedFitResult_afterFit', region='3jL', sample='', fitregions='WR,TR,S3,S4,SR3jT,SR4jT', dataname='obsData', doAsym=False, SRName=""): """ Method-2: set the parameter you're interested in constant, redo the fit with all other parameters floating, calculate the quadratic difference between default fit and your new model with parameter fixed @param filename The filename containing afterFit workspace @param resultname The name of fit result (typically='RooExpandedFitResult_afterFit' or 'RooExpandedFitResult_beforeFit' @param region The region to be used for systematics breakdown calculation @param sample The sample to be used insted of total pdf (default='' not defined, hence total pdf used) @param fitregions Fit regions to perform the re-fit (default= 'WR,TR,S3,S4,SR3jT,SR4jT' but needs to be specified by user) @param dataname The name of dataset (default='obsData') @param doAsym Calculates asymmetric errors taken from MINOS (default=False) """ """ pick up workspace from file """ w = Util.GetWorkspaceFromFile(filename, 'w') if w == None: print "ERROR : Cannot open workspace : " sys.exit(1) """ pick up RooExpandedFitResult from workspace with name resultName (either before or after fit) """ result = w.obj(resultname) if result == None: print "ERROR : Cannot open fit result : ", resultname sys.exit(1) """ save the original (after-fit result) fit parameters list """ resultlistOrig = result.floatParsFinal() """ load workspace snapshot related to resultName (=set all parameters to values after fit) """ snapshot = 'snapshot_paramsVals_' + resultname w.loadSnapshot(snapshot) """ pick up dataset from workspace """ data_set = w.data(dataname) if data_set == None: print "ERROR : Cannot open dataset : ", "data_set" sys.exit(1) """ pick up channel category (RooCategory) from workspace """ regionCat = w.obj("channelCat") # data_set.table(regionCat).Print("v"); """ find full (long) name list of region (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50) """ regionFullName = Util.GetFullRegionName(regionCat, region) """ find and save the list of all regions used for the fit, as the fit will be redone """ fitRegionsList = fitregions.split(",") fitRegionsFullName = "" for reg in fitRegionsList: regFullName = Util.GetFullRegionName(regionCat, reg) if fitRegionsFullName == "": fitRegionsFullName = regFullName.Data() else: fitRegionsFullName = fitRegionsFullName + "," + regFullName.Data() """ set a boolean whether we're looking at a sample or the full (multi-sample) pdf/model """ chosenSample = False if sample is not '': chosenSample = True """ define regSys set, for all names/numbers to be saved in """ regSys = {} """ define channelCat call for this region and reduce the dataset to this category/region """ regionCatStr = 'channelCat==channelCat::' + regionFullName.Data() dataRegion = data_set.reduce(regionCatStr) nobsRegion = 0. if dataRegion: nobsRegion = dataRegion.sumEntries() else: print " ERROR : dataset-category", regionCatStr, " not found" """ if looking at a sample, there is no equivalent N_obs (only for the full model) """ if chosenSample: regSys['sqrtnobsa'] = 0. else: regSys['sqrtnobsa'] = TMath.Sqrt(nobsRegion) """ get the pdf for the total model or just for the sample in region """ if chosenSample: pdfInRegion = Util.GetComponent(w, sample, region) else: rawPdfInRegion = Util.GetRegionPdf(w, region) varInRegion = Util.GetRegionVar(w, region) prodList = rawPdfInRegion.pdfList() foundRRS = 0 for idx in range(prodList.getSize()): if prodList[idx].InheritsFrom("RooRealSumPdf"): rrspdfInt = prodList[idx].createIntegral( RooArgSet(varInRegion)) pdfInRegion = rrspdfInt foundRRS += 1 if foundRRS > 1 or foundRRS == 0: print " \n\n WARNING: ", pdf.GetName( ), " has ", foundRRS, " instances of RooRealSumPdf" print pdf.GetName(), " component list:", prodList.Print("v") if not pdfInRegion: if chosenSample: print " \n Warning, could not find pdf in region = ", region, " for sample = ", sample else: print " \n Warning, could not find pdf in region = ", region """ calculate fitted pdf number of events and full error """ nFittedInRegion = pdfInRegion.getVal() regSys['sqrtnfitted'] = TMath.Sqrt(nFittedInRegion) regSys['nfitted'] = nFittedInRegion pdfFittedErrInRegion = Util.GetPropagatedError(pdfInRegion, result, doAsym) regSys['totsyserr'] = pdfFittedErrInRegion """ set lumi parameter constant for the refit -- FIXME """ lumiConst = True fpf = result.floatParsFinal() """ redo the fit for every parameter being fixed """ for idx in range(fpf.getSize()): parname = fpf[idx].GetName() print "\n Method-2: redoing fit with fixed parameter ", parname """ the parameter that is fixed, needs to have the value of the default fit """ w.loadSnapshot(snapshot) par = w.var(parname) par.setConstant(True) """ perform the fit again with one parameter fixed """ suffix = parname + "Fixed" result_1parfixed = Util.FitPdf(w, fitRegionsFullName, lumiConst, data_set, suffix, doAsym, "all") """ create a new RooExpandedFitResult based on the new fit and all parameters saved in the original fit result (as some parameters might only be floating in VRs) """ expResultAfter_1parfixed = RooExpandedFitResult( result_1parfixed, resultlistOrig) """ calculate newly fitted number of events and full error """ nFittedInRegion_1parfixed = pdfInRegion.getVal() pdfFittedErrInRegion_1parfixed = Util.GetPropagatedError( pdfInRegion, expResultAfter_1parfixed, doAsym) # result_1parfixed) """ check whether original total error is smaller then newly-fitted total error if one does anew fit with less floating parameters (systematics), it can be expected to see smaller error (this assumption does not take correlations into account) """ if pdfFittedErrInRegion_1parfixed > pdfFittedErrInRegion: print "\n\n WARNING parameter ", parname, " gives a larger error when set constant. Do you expect this?" print " WARNING pdfFittedErrInRegion = ", pdfFittedErrInRegion, " pdfFittedErrInRegion_1parfixed = ", pdfFittedErrInRegion_1parfixed """ calculate systematic error as the quadratic difference between original and re-fitted errors """ systError = TMath.Sqrt( abs(pdfFittedErrInRegion * pdfFittedErrInRegion - pdfFittedErrInRegion_1parfixed * pdfFittedErrInRegion_1parfixed)) par.setConstant(False) """ print a warning if new fit with 1 par fixed did not converge - meaning that sys error cannot be trusted """ if result_1parfixed.status() == 0 and result_1parfixed.covQual( ) == 3: #and result_1parfixed.numStatusHistory()==2 and result_1parfixed.statusCodeHistory(0)==0 and result_1parfixed.statusCodeHistory(1) ==0: systError = systError else: systError = 0.0 print " WARNING : for parameter ", parname, " fixed the fit does not converge, as status=", result_1parfixed.status( ), "(converged=0), and covariance matrix quality=", result_1parfixed.covQual( ), " (full accurate==3)" print " WARNING: setting systError = 0 for parameter ", parname regSys['syserr_' + parname] = systError return regSys