def signalFitInterpolation(category, ws, tupleSignalModelVariable, settings, **wargs): """ assume the Workspace already exists and x-variable is already defined """ # # initialize the values from wargs # pathToDir = "/tmp" if "pathToDir" in wargs: pathToDir = wargs["pathToDir"] # # the the canvas/frame # canvas = R.TCanvas("c1", "c1", 800, 600) canvas.cd() frame = ws.var("x").frame() # # for each mass point, perform a fit. # initial values for each consecutive model will be derived from the # previous mass point # imodel = 0 prevSignal=None; prevModel=None; prevVariable=None for (signal, model, variable) in tupleSignalModelVariable: fsdata = R.TFile(signal.pathToFile) hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1/signal.getWeight()) rsdata = aux.buildRooHist(ws, hsdata) model.initialize(aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) if imodel>0: model.setInitialValuesFromModel(prevModel, ws, massDifference=(variable["central"] - prevVariable["central"])) model.createParameters(ws) pdf = model.build(ws, category=category) r = pdf.fitTo(rsdata, R.RooFit.Save(), R.RooFit.Range(variable["fitmin"], variable["fitmax"])) prevSignal = signal prevModel = model prevVariable = variable pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) imodel+=1 # # save the canvas # frame.SetTitle("{category}_{processName}".format(category=category, processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFitInterpolation__{category}__{processName}__{modelId}__{mods}.png".format(category=category, processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="") canvas.SaveAs(os.path.join(pathToDir, fileName))
def datacardsSingleGaus(): physGroupToUse = physGroupTest orderedGroupsToUse = orderedGroupsTest workspaceName = "higgs" signalSplinesDir = os.path.join(signalfitinterpolationswithsplineDir, args.outDirName) backgroundsDir = os.path.join(backgroundfitswithroomultipdfDir, args.outDirName) datacardsDir = os.path.join(datacardsworkspacesDir, args.outDirName) fffTestDir = os.path.join(ftestDir, args.outDirName) aux.mkdir(signalSplinesDir) aux.mkdir(backgroundsDir) aux.mkdir(datacardsDir) aux.mkdir(fffTestDir) fTestResults = {} for category in categoriesToUse: fTestResults[category] = {} workspaceFileName = "workspace__{category}__{signalModelId}.root".format( category=names2RepsToUse[category], signalModelId=singleGaus120.modelId) ws = R.RooWorkspace(workspaceName) aux.buildMassVariable(ws, **diMuonMass125) aux.buildMH(ws, mhmin=120, mhmax=130) # # create the RooDataHist and import it into the Workspace here explicitly # fdata = R.TFile(data.pathToFile) hdata_name = category + "/DiMuonMass" if settings.useInputFileUF: hdata_name = "net_histos/" + category + "_Net_Data" hdata = fdata.Get(hdata_name) rdata = aux.buildRooHist( ws, hdata, "data_obs_{category}".format(category=names2RepsToUse[category])) getattr(ws, "import")(rdata, R.RooFit.RecycleConflictNodes()) fdata.Close() # # Create the Signal Models # print "*" * 80 print "Generating Single Gaus Splines" print "*" * 80 vbfmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (vbf120, singleGaus120, diMuonMass120), (vbf125, singleGaus125, diMuonMass125), (vbf130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) glumodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (glu120, singleGaus120, diMuonMass120), (glu125, singleGaus125, diMuonMass125), (glu130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) wpmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (wp120, singleGaus120, diMuonMass120), (wp125, singleGaus125, diMuonMass125), (wp130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) wmmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (wm120, singleGaus120, diMuonMass120), (wm125, singleGaus125, diMuonMass125), (wm130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) zhmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (zh120, singleGaus120, diMuonMass120), (zh125, singleGaus125, diMuonMass125), (zh130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) # # Perform the F-Test and select the proper order of the # selectedOrderedModels = [] for modelGroup in orderedGroupsToUse: counter = 0 for m in modelGroup.models: m.color = colors[counter] counter += 1 selectedModel, values = funcs.ftestPerFamily( (category, diMuonMass125), ws, data, modelGroup, settings, pathToDir=fffTestDir) if selectedModel is not None: selectedOrderedModels.append(selectedModel) fTestResults[category][modelGroup.name] = values # # Create the Background Model # totalModelGroup = ModelGroup( "bkgModels", physGroupTest.models + selectedOrderedModels) counter = 0 for model in totalModelGroup.models: model.color = colors[counter] counter += 1 funcs.backgroundsWithRooMultiPdf((category, diMuonMass125), ws, data, totalModelGroup.models, settings, pathToDir=backgroundsDir, groupName=totalModelGroup.name) # # Signal and Background Models are ready and are in the Workspace # create the datacard for this category # funcs.datacardAnalytic(category, ws, data, [vbfmodel, glumodel, wpmodel, wmmodel, zhmodel], ws.pdf("multipdf_{category}".format( category=names2RepsToUse[category])), settings, pathToDir=datacardsDir, workspaceFileName=workspaceFileName, workspaceName=workspaceName, withSystematics=args.withSystematics) # # save the Workspacee # print "*" * 80 print "*** Final RooWorkspace contents ***" print "*" * 80 ws.Print("v") ws.SaveAs(os.path.join(datacardsDir, workspaceFileName)) # # plot all the F-Test Results # funcs.plotFTestResults(fTestResults, pathToDir=fffTestDir)
def datacardsTripleGaus(): physGroupToUse = physGroupTest # The physics derived background fit functions (non ordered) orderedGroupsToUse = orderedGroupsTest # The ordered background fits (berenstein, sumexp, etc) # book keeping, set up output dirs for signal, bkg, datacards, and workspaces workspaceName = "higgs" signalSplinesDir = os.path.join(signalfitinterpolationswithsplineDir, args.outDirName) backgroundsDir = os.path.join(backgroundfitswithroomultipdfDir, args.outDirName) datacardsDir = os.path.join(datacardsworkspacesDir, args.outDirName) fffTestDir = os.path.join(ftestDir, args.outDirName) aux.mkdir(signalSplinesDir) aux.mkdir(backgroundsDir) aux.mkdir(datacardsDir) aux.mkdir(fffTestDir) fTestResults = {} # run over every category and fit the signal and background and make the workspaces for category in categoriesToUse: fTestResults[category] = {} # Create workspace for category # use the representation of the name rather than the complicated name, should set up reps in config file workspaceFileName = "workspace__{category}__{signalModelId}.root".format( category=names2RepsToUse[category], signalModelId=tripleGaus120.modelId) ws = R.RooWorkspace(workspaceName) aux.buildMassVariable(ws, **diMuonMass125) aux.buildMH(ws, mhmin=120, mhmax=130) # # Create the RooDataHist and import it into the Workspace # fdata = R.TFile(data.pathToFile) hdata_name = category + "/DiMuonMass" if settings.useInputFileUF: hdata_name = "net_histos/" + category + "_Net_Data" # Get data histogram from the input file for the category # Turn it into a roo data histogram to use with roofit hdata = fdata.Get(hdata_name) rdata = aux.buildRooHist( ws, hdata, "data_obs_{category}".format(category=names2RepsToUse[category])) getattr(ws, "import")(rdata, R.RooFit.RecycleConflictNodes()) fdata.Close() # # Create the Signal Models # print "*" * 80 print "Generating Triple Gaus Splines" print "*" * 80 # vbf120, tripleGaus120, diMuonMass120 imported from config file # vbf120 is of defs.MC('NoCats', inputFileUF, vbf120MC, color=R.kRed) # vbf120MC = samp.mcMoriond2017datasets_1['VBF_120'] # tripleGaus120 = models.TripleGaus(tripleGaus120_initialValues) # diMuonMass120 = {name: DiMuonMass, central: 120, min:110, max:160, fitmin:110, fitmax:130} vbfmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (vbf120, tripleGaus120, diMuonMass120), # (mc sample, fit, fit window) (vbf125, tripleGaus125, diMuonMass125), (vbf130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) glumodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (glu120, tripleGaus120, diMuonMass120), (glu125, tripleGaus125, diMuonMass125), (glu130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) wpmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (wp120, tripleGaus120, diMuonMass120), (wp125, tripleGaus125, diMuonMass125), (wp130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) wmmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (wm120, tripleGaus120, diMuonMass120), (wm125, tripleGaus125, diMuonMass125), (wm130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) zhmodel = funcs.signalFitInterpolationWithSpline( category, ws, [ (zh120, tripleGaus120, diMuonMass120), (zh125, tripleGaus125, diMuonMass125), (zh130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir) # # Perform the F-Test and select the proper order of the # selectedOrderedModels = [ ] # ordered models for this category that passed the f-test for modelGroup in orderedGroupsToUse: # ModelGroup has a name for the group and a list of models counter = 0 for m in modelGroup.models: m.color = colors[counter] counter += 1 # return the model with the order that passes the ftest # e.g. berenstein6 for berensten model group or sumExp3 for sum exp model group # ftestPerFamily imported from Modeling/higgs2/generatingFunctions.py selectedModel, values = funcs.ftestPerFamily( (category, diMuonMass125), ws, data, modelGroup, settings, pathToDir=fffTestDir, unblind=args.unblind) if selectedModel is not None: selectedOrderedModels.append(selectedModel) # Save ftest results for each category,modelgroup fTestResults[category][modelGroup.name] = values # # Create the Background Model # totalModelGroup = ModelGroup( "bkgModels", physGroupTest.models + selectedOrderedModels) counter = 0 for model in totalModelGroup.models: model.color = colors[counter] counter += 1 # Multipdf for background with physics based models and the ftest passed ordered models # !!! DOES NOT use modelGroupForMultiPdf from config file !!! funcs.backgroundsWithRooMultiPdf((category, diMuonMass125), ws, data, totalModelGroup.models, settings, pathToDir=backgroundsDir, groupName=totalModelGroup.name, unblind=args.unblind) # # Signal and Background Models are ready and are in the Workspace # create the datacard for this category # funcs.datacardAnalytic(category, ws, data, [vbfmodel, glumodel, wpmodel, wmmodel, zhmodel], ws.pdf("multipdf_{category}".format( category=names2RepsToUse[category])), settings, pathToDir=datacardsDir, workspaceFileName=workspaceFileName, workspaceName=workspaceName, withSystematics=args.withSystematics) # # save the Workspacee # ws.SaveAs(os.path.join(datacardsDir, workspaceFileName)) # # plot all the F-test results # funcs.plotFTestResults(fTestResults, pathToDir=fffTestDir)
def signalFitInterpolation(category, ws, tupleSignalModelVariable, settings, **wargs): """ assume the Workspace already exists and x-variable is already defined """ # # initialize the values from wargs # pathToDir = "/tmp" if "pathToDir" in wargs: pathToDir = wargs["pathToDir"] # # the the canvas/frame # canvas = R.TCanvas("c1", "c1", 800, 600) canvas.cd() frame = ws.var("x").frame() # # for each mass point, perform a fit. # initial values for each consecutive model will be derived from the # previous mass point # imodel = 0 prevSignal = None prevModel = None prevVariable = None for (signal, model, variable) in tupleSignalModelVariable: fsdata = R.TFile(signal.pathToFile) hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1 / signal.getWeight()) rsdata = aux.buildRooHist(ws, hsdata) model.initialize( aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) if imodel > 0: model.setInitialValuesFromModel( prevModel, ws, massDifference=(variable["central"] - prevVariable["central"])) model.createParameters(ws) pdf = model.build(ws, category=category) r = pdf.fitTo(rsdata, R.RooFit.Save(), R.RooFit.Range(variable["fitmin"], variable["fitmax"])) prevSignal = signal prevModel = model prevVariable = variable pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) imodel += 1 # # save the canvas # frame.SetTitle("{category}_{processName}".format( category=category, processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFitInterpolation__{category}__{processName}__{modelId}__{mods}.png".format( category=category, processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="") canvas.SaveAs(os.path.join(pathToDir, fileName))
def signalFitInterpolationWithSpline(category, ws, tupleSignalModelVariable, settings, **wargs): """ assume the Workspace already exists and x-variable is already defined """ # # Load Combine's lib # R.gSystem.Load("libHiggsAnalysisCombinedLimit.so") # # initialize the values from wargs # pathToDir = "/tmp" if "pathToDir" in wargs: pathToDir = wargs["pathToDir"] # # the the canvas/frame # canvas = R.TCanvas("c1", "c1", 800, 600) canvas.cd() # # for each mass point, perform a fit. # initial values for each consecutive model will be derived from the # previous mass point # imodel = 0 prevSignal = None prevModel = None prevVariable = None parameters = [] massPoints = [] norms = [] for (signal, model, variable) in tupleSignalModelVariable: fsdata = R.TFile(signal.pathToFile) frame = ws.var("x").frame() hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1 / signal.getWeight()) rsdata = aux.buildRooHist(ws, hsdata) binfirst = hsdata.FindBin(variable["min"]) binlast = hsdata.FindBin(variable["max"]) # norms.append(hsdata.Integral(binfirst, binlast)) norms.append(rsdata.sumEntries()) model.initialize( aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) if imodel > 0: model.setInitialValuesFromModel( prevModel, ws, massDifference=(variable["central"] - prevVariable["central"])) model.createParameters(ws) pdf = model.build(ws, category=category) # # Fit twice??? # Andrea has it like that??? May be second time has better initial values??? # r = pdf.fitTo(rsdata, R.RooFit.Save(), R.RooFit.Range(variable["fitmin"], variable["fitmax"]), R.RooFit.SumW2Error(R.kTRUE)) prevSignal = signal prevModel = model prevVariable = variable imodel += 1 massPoints.append(variable["central"]) # plot this model together with signal histogram rsdata.plotOn(frame) pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) # draw the frame and save the canvas frame.SetTitle("{category}_{higgsMass}_{processName}".format( category=category, higgsMass=variable["central"], processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFit__{category}__{higgsMass}__{processName}__{modelId}__{mods}.png".format( category=category, higgsMass=variable["central"], processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="default") canvas.SaveAs(os.path.join(pathToDir, fileName)) # exctract the parameters lParameters = model.getParameterValuesAsList(ws) parameters.append(lParameters) print "*" * 90 + "\n" print "*" * 90 + "\n" print lParameters print parameters r.Print("v") # pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) imodel += 1 # # build the Splines # create the spline for normalization # have to transpose the matrix of parameters first # frame = ws.var("x").frame() paramsTransposed = aux.transpose(parameters) print "*" * 90 + "\n" print "*" * 90 + "\n" print "*" * 90 + "\n" print "*" * 90 + "\n" print parameters print paramsTransposed finalmodel = prevModel.__class__() finalmodel.initialize( aux.buildSignalModelName(finalmodel, settings.names2RepsToUse[category], signal.mc.buildProcessName())) finalpdf = finalmodel.buildWithParameterMatrix(ws, massPoints, paramsTransposed) finalmodel.setNormalization(ws, massPoints, norms) finalpdf.Print("v") # # plot for each GeV and save the canvas # for mh in [120 + i for i in range(11)]: ws.var("MH").setVal(mh) finalpdf.plotOn(frame) # # save the canvas # frame.SetTitle("{category}_{processName}".format( category=category, processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFitInterpolationWithSpline__{category}__{processName}__{modelId}__{mods}.png".format( category=category, processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="") canvas.SaveAs(os.path.join(pathToDir, fileName)) # # return the model that you build with RooSplines # return finalmodel
# get the histogram from the input root file # and convert to a roo hist # fsdata = R.TFile(signal.pathToFile) hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1 / signal.getWeight()) # hsdata.GetXaxis().SetRange(variable["min"], variable["max"]) rsdata = aux.buildRooHist(ws, hsdata) # # set up the model and perform the fit # # Simply set the name for the model based upon the model, category, and M=120,125,or 130 model.initialize( aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) # Set the initial signal model parameters based upon the mean and rms of the signal histogram # for this category, seems reasonable for single gauss, but not sure what it does for double # and triple gauss if initialValuesFromTH1:
def datacardsTripleGaus(): physGroupToUse = physGroupTest # The physics derived background fit functions (non ordered) orderedGroupsToUse = orderedGroupsTest # The ordered background fits (berenstein, sumexp, etc) # book keeping, set up output dirs for signal, bkg, datacards, and workspaces workspaceName = "higgs" signalSplinesDir = os.path.join(signalfitinterpolationswithsplineDir, args.outDirName) backgroundsDir = os.path.join(backgroundfitswithroomultipdfDir, args.outDirName) datacardsDir = os.path.join(datacardsworkspacesDir, args.outDirName) fffTestDir = os.path.join(ftestDir, args.outDirName) aux.mkdir(signalSplinesDir); aux.mkdir(backgroundsDir); aux.mkdir(datacardsDir) aux.mkdir(fffTestDir) fTestResults = {} # run over every category and fit the signal and background and make the workspaces for category in categoriesToUse: fTestResults[category] = {} # Create workspace for category # use the representation of the name rather than the complicated name, should set up reps in config file workspaceFileName = "workspace__{category}__{signalModelId}.root".format( category=names2RepsToUse[category], signalModelId = tripleGaus120.modelId) ws = R.RooWorkspace(workspaceName) aux.buildMassVariable(ws, **diMuonMass125) aux.buildMH(ws, mhmin=120, mhmax=130) # # Create the RooDataHist and import it into the Workspace # fdata = R.TFile(data.pathToFile) hdata_name = category + "/DiMuonMass" if settings.useInputFileUF: hdata_name = "net_histos/"+category+"_Net_Data" # Get data histogram from the input file for the category # Turn it into a roo data histogram to use with roofit hdata = fdata.Get(hdata_name) rdata = aux.buildRooHist(ws, hdata, "data_obs_{category}".format(category=names2RepsToUse[category])) getattr(ws, "import")(rdata, R.RooFit.RecycleConflictNodes()) fdata.Close() # # Create the Signal Models # print "*"*80 print "Generating Triple Gaus Splines" print "*"*80 # vbf120, tripleGaus120, diMuonMass120 imported from config file # vbf120 is of defs.MC('NoCats', inputFileUF, vbf120MC, color=R.kRed) # vbf120MC = samp.mcMoriond2017datasets_1['VBF_120'] # tripleGaus120 = models.TripleGaus(tripleGaus120_initialValues) # diMuonMass120 = {name: DiMuonMass, central: 120, min:110, max:160, fitmin:110, fitmax:130} vbfmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (vbf120, tripleGaus120, diMuonMass120), # (mc sample, fit, fit window) (vbf125, tripleGaus125, diMuonMass125), (vbf130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) glumodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (glu120, tripleGaus120, diMuonMass120), (glu125, tripleGaus125, diMuonMass125), (glu130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) wpmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (wp120, tripleGaus120, diMuonMass120), (wp125, tripleGaus125, diMuonMass125), (wp130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) wmmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (wm120, tripleGaus120, diMuonMass120), (wm125, tripleGaus125, diMuonMass125), (wm130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) zhmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (zh120, tripleGaus120, diMuonMass120), (zh125, tripleGaus125, diMuonMass125), (zh130, tripleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) # # Perform the F-Test and select the proper order of the # selectedOrderedModels = [] # ordered models for this category that passed the f-test for modelGroup in orderedGroupsToUse: # ModelGroup has a name for the group and a list of models counter = 0; for m in modelGroup.models: m.color = colors[counter] counter+=1 # return the model with the order that passes the ftest # e.g. berenstein6 for berensten model group or sumExp3 for sum exp model group # ftestPerFamily imported from Modeling/higgs2/generatingFunctions.py selectedModel, values = funcs.ftestPerFamily( (category, diMuonMass125), ws, data, modelGroup, settings, pathToDir=fffTestDir, unblind=args.unblind) if selectedModel is not None: selectedOrderedModels.append(selectedModel) # Save ftest results for each category,modelgroup fTestResults[category][modelGroup.name] = values # # Create the Background Model # totalModelGroup = ModelGroup("bkgModels", physGroupTest.models + selectedOrderedModels) counter = 0 for model in totalModelGroup.models: model.color = colors[counter] counter += 1 # Multipdf for background with physics based models and the ftest passed ordered models # !!! DOES NOT use modelGroupForMultiPdf from config file !!! funcs.backgroundsWithRooMultiPdf((category, diMuonMass125), ws, data, totalModelGroup.models, settings, pathToDir=backgroundsDir, groupName=totalModelGroup.name, unblind=args.unblind) # # Signal and Background Models are ready and are in the Workspace # create the datacard for this category # funcs.datacardAnalytic(category, ws, data, [vbfmodel, glumodel, wpmodel, wmmodel, zhmodel], ws.pdf("multipdf_{category}".format(category=names2RepsToUse[category])), settings, pathToDir=datacardsDir, workspaceFileName=workspaceFileName, workspaceName=workspaceName, withSystematics=args.withSystematics ) # # save the Workspacee # ws.SaveAs(os.path.join(datacardsDir, workspaceFileName)) # # plot all the F-test results # funcs.plotFTestResults(fTestResults, pathToDir=fffTestDir)
def datacardsSingleGaus(): physGroupToUse = physGroupTest orderedGroupsToUse = orderedGroupsTest workspaceName = "higgs" signalSplinesDir = os.path.join(signalfitinterpolationswithsplineDir, args.outDirName) backgroundsDir = os.path.join(backgroundfitswithroomultipdfDir, args.outDirName) datacardsDir = os.path.join(datacardsworkspacesDir, args.outDirName) fffTestDir = os.path.join(ftestDir, args.outDirName) aux.mkdir(signalSplinesDir); aux.mkdir(backgroundsDir); aux.mkdir(datacardsDir) aux.mkdir(fffTestDir) fTestResults = {} for category in categoriesToUse: fTestResults[category] = {} workspaceFileName = "workspace__{category}__{signalModelId}.root".format( category=names2RepsToUse[category], signalModelId = singleGaus120.modelId) ws = R.RooWorkspace(workspaceName) aux.buildMassVariable(ws, **diMuonMass125) aux.buildMH(ws, mhmin=120, mhmax=130) # # create the RooDataHist and import it into the Workspace here explicitly # fdata = R.TFile(data.pathToFile) hdata_name = category + "/DiMuonMass" if settings.useInputFileUF: hdata_name = "net_histos/"+category+"_Net_Data" hdata = fdata.Get(hdata_name) rdata = aux.buildRooHist(ws, hdata, "data_obs_{category}".format(category=names2RepsToUse[category])) getattr(ws, "import")(rdata, R.RooFit.RecycleConflictNodes()) fdata.Close() # # Create the Signal Models # print "*"*80 print "Generating Single Gaus Splines" print "*"*80 vbfmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (vbf120, singleGaus120, diMuonMass120), (vbf125, singleGaus125, diMuonMass125), (vbf130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) glumodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (glu120, singleGaus120, diMuonMass120), (glu125, singleGaus125, diMuonMass125), (glu130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) wpmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (wp120, singleGaus120, diMuonMass120), (wp125, singleGaus125, diMuonMass125), (wp130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) wmmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (wm120, singleGaus120, diMuonMass120), (wm125, singleGaus125, diMuonMass125), (wm130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) zhmodel = funcs.signalFitInterpolationWithSpline(category, ws, [ (zh120, singleGaus120, diMuonMass120), (zh125, singleGaus125, diMuonMass125), (zh130, singleGaus130, diMuonMass130), ], settings, pathToDir=signalSplinesDir ) # # Perform the F-Test and select the proper order of the # selectedOrderedModels = [] for modelGroup in orderedGroupsToUse: counter = 0; for m in modelGroup.models: m.color = colors[counter] counter+=1 selectedModel, values = funcs.ftestPerFamily( (category, diMuonMass125), ws, data, modelGroup, settings, pathToDir=fffTestDir) if selectedModel is not None: selectedOrderedModels.append(selectedModel) fTestResults[category][modelGroup.name] = values # # Create the Background Model # totalModelGroup = ModelGroup("bkgModels", physGroupTest.models + selectedOrderedModels) counter = 0 for model in totalModelGroup.models: model.color = colors[counter] counter += 1 funcs.backgroundsWithRooMultiPdf((category, diMuonMass125), ws, data, totalModelGroup.models, settings, pathToDir=backgroundsDir, groupName=totalModelGroup.name) # # Signal and Background Models are ready and are in the Workspace # create the datacard for this category # funcs.datacardAnalytic(category, ws, data, [vbfmodel, glumodel, wpmodel, wmmodel, zhmodel], ws.pdf("multipdf_{category}".format(category=names2RepsToUse[category])), settings, pathToDir=datacardsDir, workspaceFileName=workspaceFileName, workspaceName=workspaceName, withSystematics=args.withSystematics ) # # save the Workspacee # print "*"*80 print "*** Final RooWorkspace contents ***" print "*"*80 ws.Print("v") ws.SaveAs(os.path.join(datacardsDir, workspaceFileName)) # # plot all the F-Test Results # funcs.plotFTestResults(fTestResults, pathToDir=fffTestDir)
def signalFitInterpolationWithSpline(category, ws, tupleSignalModelVariable, settings, **wargs): """ assume the Workspace already exists and x-variable is already defined """ # # Load Combine's lib # R.gSystem.Load("libHiggsAnalysisCombinedLimit.so") # # initialize the values from wargs # pathToDir = "/tmp" if "pathToDir" in wargs: pathToDir = wargs["pathToDir"] # # the the canvas/frame # canvas = R.TCanvas("c1", "c1", 800, 600) canvas.cd() # # for each mass point, perform a fit. # initial values for each consecutive model will be derived from the # previous mass point # imodel = 0 prevSignal=None; prevModel=None; prevVariable=None parameters = [] massPoints = [] norms = [] for (signal, model, variable) in tupleSignalModelVariable: fsdata = R.TFile(signal.pathToFile) frame = ws.var("x").frame() hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1/signal.getWeight()) rsdata = aux.buildRooHist(ws, hsdata) binfirst = hsdata.FindBin(variable["min"]) binlast = hsdata.FindBin(variable["max"]) # norms.append(hsdata.Integral(binfirst, binlast)) norms.append(rsdata.sumEntries()) model.initialize(aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) if imodel>0: model.setInitialValuesFromModel(prevModel, ws, massDifference=(variable["central"] - prevVariable["central"])) model.createParameters(ws) pdf = model.build(ws, category=category) # # Fit twice??? # Andrea has it like that??? May be second time has better initial values??? # r = pdf.fitTo(rsdata, R.RooFit.Save(), R.RooFit.Range(variable["fitmin"], variable["fitmax"]), R.RooFit.SumW2Error(R.kTRUE)) prevSignal = signal prevModel = model prevVariable = variable imodel +=1 massPoints.append(variable["central"]) # plot this model together with signal histogram rsdata.plotOn(frame) pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) # draw the frame and save the canvas frame.SetTitle("{category}_{higgsMass}_{processName}".format(category=category, higgsMass=variable["central"], processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFit__{category}__{higgsMass}__{processName}__{modelId}__{mods}.png".format( category=category, higgsMass=variable["central"], processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="default") canvas.SaveAs(os.path.join(pathToDir, fileName)) # exctract the parameters lParameters = model.getParameterValuesAsList(ws) parameters.append(lParameters) print "*"*90 + "\n" print "*"*90 + "\n" print lParameters print parameters r.Print("v") # pdf.plotOn(frame, R.RooFit.LineColor(R.kBlue)) imodel+=1 # # build the Splines # create the spline for normalization # have to transpose the matrix of parameters first # frame = ws.var("x").frame() paramsTransposed = aux.transpose(parameters) print "*"*90 + "\n" print "*"*90 + "\n" print "*"*90 + "\n" print "*"*90 + "\n" print parameters print paramsTransposed finalmodel = prevModel.__class__() finalmodel.initialize(aux.buildSignalModelName(finalmodel, settings.names2RepsToUse[category], signal.mc.buildProcessName())) finalpdf = finalmodel.buildWithParameterMatrix(ws, massPoints, paramsTransposed) finalmodel.setNormalization(ws, massPoints, norms) finalpdf.Print("v") # # plot for each GeV and save the canvas # for mh in [120+i for i in range(11)]: ws.var("MH").setVal(mh) finalpdf.plotOn(frame) # # save the canvas # frame.SetTitle("{category}_{processName}".format(category=category, processName=signal.mc.buildProcessName())) frame.Draw() fileName = "signalFitInterpolationWithSpline__{category}__{processName}__{modelId}__{mods}.png".format(category=category, processName=signal.mc.buildProcessName(), modelId=model.modelId, mods="") canvas.SaveAs(os.path.join(pathToDir, fileName)) # # return the model that you build with RooSplines # return finalmodel
# # get the histogram from the input root file # and convert to a roo hist # fsdata = R.TFile(signal.pathToFile) hsdata_name = category + "/" + variable["name"] if settings.useInputFileUF: hsdata_name = "signal_histos/" + category + "_" + signal.mc.uflabel hsdata = fsdata.Get(hsdata_name) if not settings.useInputFileUF: hsdata.Scale(1/signal.getWeight()) # hsdata.GetXaxis().SetRange(variable["min"], variable["max"]) rsdata = aux.buildRooHist(ws, hsdata) # # set up the model and perform the fit # # Simply set the name for the model based upon the model, category, and M=120,125,or 130 model.initialize(aux.buildSignalModelName(model, settings.names2RepsToUse[category], signal.mc.buildProcessName(), variable["central"])) # Set the initial signal model parameters based upon the mean and rms of the signal histogram # for this category, seems reasonable for single gauss, but not sure what it does for double # and triple gauss if initialValuesFromTH1: model.setInitialValuesFromTH1(hsdata) model.createParameters(ws) # Create params for model and add to workspace