Пример #1
0
def latexfitresults( filename, namemap, region='3jL', sample='', resultName="RooExpandedFitResult_afterFit", dataname='obsData', doAsym=True):
  """
  Method-1: set all parameters constant, except for the one you're interested in, 
           calculate the systematic/error propagated due to that parameter

  @param filename The filename containing afterFit workspace
  @param namemap Defines whether any systematics need to be grouped in calculation (by default not defined, hence each parameter gets used one by one)
  @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 dataname The name of dataset (default='obsData')
  @param doAsym Calculates asymmetric errors taken from MINOS (default=True)
"""

  """
  pick up workspace from file
  """
  workspacename = 'w'
  w = Util.GetWorkspaceFromFile(filename,workspacename)
  if w==None:
    print "ERROR : Cannot open workspace : ", workspacename
    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)

  """
  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);

  """
  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)
  
  """
  retrieve and save number of observed (=data) events in region
  """
  nobsRegion = 0.
  if dataRegion:
    nobsRegion = dataRegion.sumEntries()
  else:
    print " ERROR : dataset-category dataRegion 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=getPdfInRegions(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


  """
  calculate error per (floating) parameter in fitresult
  get a list of floating parameters to loop over
  """
  fpf = result.floatParsFinal() 
  
  """
  set all floating parameters constant
  """
  for idx in range(fpf.getSize()):
    parname = fpf[idx].GetName()
    par = w.var(parname)
    par.setConstant()

  """
  if several systematatic/parameters are pre-defined in namemap, they will be floated together
  or in other words, one will get the error due to all pre-defined systematics
  """
  """
  else, float each parameter one by one and calculate the error due to it
  """
  if len(namemap)>0: 
    for key in namemap.keys():
      print namemap[key]
      for parname in namemap[key]:
        par = w.var(parname)
        par.setConstant(False)
        pass
      sysError  = Util.GetPropagatedError(pdfInRegion, result, doAsym)
      regSys['syserr_'+key] =  sysError
      for idx in range(fpf.getSize()):
        parname = fpf[idx].GetName()
        par = w.var(parname)
        par.setConstant()
        pass
  else: 
    for idx in range(fpf.getSize()):
      parname = fpf[idx].GetName()
      par = w.var(parname)
      par.setConstant(False)
      sysError  = Util.GetPropagatedError(pdfInRegion, result, doAsym)
      regSys['syserr_'+parname] =  sysError
      par.setConstant() 

  return regSys
Пример #2
0
def latexfitresults(filename,regionList,sampleList,exactRegionNames=False,dataname='obsData',showSum=False, doAsym=True, blinded=False):
  workspacename = 'w'
  w = Util.GetWorkspaceFromFile(filename,'w')

  if w==None:
    print "ERROR : Cannot open workspace : ", workspacename
    sys.exit(1) 

  resultAfterFit = w.obj('RooExpandedFitResult_afterFit')
  if resultAfterFit==None:
    print "ERROR : Cannot open fit result after fit RooExpandedFitResult_afterFit"
    sys.exit(1)

  resultBeforeFit = w.obj('RooExpandedFitResult_beforeFit')
  if resultBeforeFit==None:
    print "ERROR : Cannot open fit result before fit RooExpandedFitResult_beforeFit"
    sys.exit(1)

  data_set = w.data(dataname)
  if data_set==None:
    print "ERROR : Cannot open dataset : ", "data_set"+suffix
    sys.exit(1)
      
  regionCat = w.obj("channelCat")
  data_set.table(regionCat).Print("v");

  regionFullNameList = [ Util.GetFullRegionName(regionCat, region) for region in regionList]
  print regionFullNameList

  ######

  snapshot =  'snapshot_paramsVals_RooExpandedFitResult_afterFit'
  w.loadSnapshot(snapshot)

  if not w.loadSnapshot(snapshot):
    print "ERROR : Cannot load snapshot : ", snapshot
    sys.exit(1)

  tablenumbers = {}

  # SUM ALL REGIONS
  sumName = ""
  for index, reg in enumerate(regionList):
    if index == 0:
      sumName = reg
    else:
      sumName = sumName + " + " + reg
  
  regionListWithSum = list(regionList)
  if showSum:
    regionListWithSum.append(sumName)

  tablenumbers['names'] = regionListWithSum

  regionCatList = [ 'channelCat==channelCat::' +region.Data() for region in regionFullNameList]
  
  regionDatasetList = [data_set.reduce(regioncat) for regioncat in regionCatList]
  for index, data in enumerate(regionDatasetList):
    data.SetName("data_" + regionList[index])
    data.SetTitle("data_" + regionList[index])
    
  nobs_regionList = [ data.sumEntries() for data in regionDatasetList]
  #SUM
  sumNobs = 0.
  for nobs in nobs_regionList:
    sumNobs += nobs
    ## print " \n XXX nobs = ", nobs, "    sumNobs = ", sumNobs
  if showSum:
    nobs_regionList.append(sumNobs)
  tablenumbers['nobs'] = nobs_regionList
 
  ######
  ######
  ######  FROM HERE ON OUT WE CALCULATE THE FITTED NUMBER OF EVENTS __AFTER__ THE FIT
  ######
  ######

  # total pdf, not splitting in components
  pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in regionList]
  varinRegionList =  [ Util.GetRegionVar(w, region) for region in regionList]
  rrspdfinRegionList = []
  for index,pdf in enumerate(pdfinRegionList):
#    pdf.Print("t")
    prodList = pdf.pdfList()
    foundRRS = 0
    for idx in range(prodList.getSize()):
      #      if "BG" in prodList[idx].GetName():
      #        prodList[idx].Print("t")
      if prodList[idx].InheritsFrom("RooRealSumPdf"):
        rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]));
        rrspdfinRegionList.append(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")
    
  nFittedInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
  pdfFittedErrInRegionList = [ Util.GetPropagatedError(pdf, resultAfterFit, doAsym) for pdf in rrspdfinRegionList]

  if showSum:
    pdfInAllRegions = RooArgSet()
    for index, pdf in enumerate(rrspdfinRegionList):
      pdfInAllRegions.add(pdf)
    pdfSumInAllRegions = RooAddition( "pdf_AllRegions_AFTER", "pdf_AllRegions_AFTER", RooArgList(pdfInAllRegions))
    pdfSumInAllRegions.Print()
    nPdfSumVal = pdfSumInAllRegions.getVal()
    nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions, resultAfterFit, doAsym)
    nFittedInRegionList.append(nPdfSumVal)
    pdfFittedErrInRegionList.append(nPdfSumError)
  
  tablenumbers['TOTAL_FITTED_bkg_events']    =  nFittedInRegionList
  tablenumbers['TOTAL_FITTED_bkg_events_err']    =  pdfFittedErrInRegionList
 
  if blinded: 
    nobs_regionList = [ data.sumEntries() for data in regionDatasetList]
    nobs_regionList[-1] = -1
    tablenumbers['nobs'] = nobs_regionList

  # components
  for isam, sample in enumerate(sampleList):
    sampleName=getName(sample)
    nSampleInRegionVal = []
    nSampleInRegionError = []
    sampleInAllRegions = RooArgSet()
    for ireg, region in enumerate(regionList):
      sampleInRegion=getPdfInRegions(w,sample,region)
      #sampleInRegion = Util.GetComponent(w,sample,region,exactRegionNames)
      sampleInRegionVal = 0.
      sampleInRegionError = 0.
      if not sampleInRegion==None:
        sampleInRegion.Print()
        sampleInRegionVal = sampleInRegion.getVal()
        sampleInRegionError = Util.GetPropagatedError(sampleInRegion, resultAfterFit, doAsym) 
        sampleInAllRegions.add(sampleInRegion)
      else:
        print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region =",region, "\n"
      nSampleInRegionVal.append(sampleInRegionVal)
      nSampleInRegionError.append(sampleInRegionError)
    if showSum:
      sampleSumInAllRegions = RooAddition( (sampleName+"_AllRegions_FITTED"), (sampleName+"_AllRegions_FITTED"), RooArgList(sampleInAllRegions))
      sampleSumInAllRegions.Print()
      nSampleSumVal = sampleSumInAllRegions.getVal()
      nSampleSumError = Util.GetPropagatedError(sampleSumInAllRegions, resultAfterFit, doAsym)
      nSampleInRegionVal.append(nSampleSumVal)
      nSampleInRegionError.append(nSampleSumError)
    tablenumbers['Fitted_events_'+sampleName]   = nSampleInRegionVal
    tablenumbers['Fitted_err_'+sampleName]   = nSampleInRegionError

  print tablenumbers

  ######
  ######
  ######  FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS __BEFORE__ THE FIT
  ######
  ######

  #  FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS BEFORE THE FIT
  w.loadSnapshot('snapshot_paramsVals_RooExpandedFitResult_beforeFit')

  # check if any of the initial scaling factors is != 1
  _result = w.obj('RooExpandedFitResult_beforeFit')
  _muFacs = _result.floatParsFinal()

  for i in range(len(_muFacs)):
    if "mu_" in _muFacs[i].GetName() and _muFacs[i].getVal() != 1.0:
      print  " \n WARNING: scaling factor %s != 1.0 (%g) expected MC yield WILL BE WRONG!" % (_muFacs[i].GetName(), _muFacs[i].getVal())
  
  pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in regionList]
  varinRegionList =  [ Util.GetRegionVar(w, region) for region in regionList]
  rrspdfinRegionList = []
  for index,pdf in enumerate(pdfinRegionList):
    prodList = pdf.pdfList()
    foundRRS = 0
    for idx in range(prodList.getSize()):
      if prodList[idx].InheritsFrom("RooRealSumPdf"):
        prodList[idx].Print()
        rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]))
        rrspdfinRegionList.append(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")

  nExpInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
  pdfExpErrInRegionList = [ Util.GetPropagatedError(pdf, resultBeforeFit, doAsym)  for pdf in rrspdfinRegionList]
  
  if showSum:
    pdfInAllRegions = RooArgSet()
    for index, pdf in enumerate(rrspdfinRegionList):
      pdfInAllRegions.add(pdf)
    pdfSumInAllRegions = RooAddition( "pdf_AllRegions_BEFORE", "pdf_AllRegions_BEFORE", RooArgList(pdfInAllRegions))
    nPdfSumVal = pdfSumInAllRegions.getVal()
    nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions, resultBeforeFit, doAsym)
    nExpInRegionList.append(nPdfSumVal)
    pdfExpErrInRegionList.append(nPdfSumError)
  
  tablenumbers['TOTAL_MC_EXP_BKG_events']    =  nExpInRegionList
  tablenumbers['TOTAL_MC_EXP_BKG_err']    =  pdfExpErrInRegionList
  
  for isam, sample in enumerate(sampleList):
    sampleName=getName(sample)
    nMCSampleInRegionVal = []
    nMCSampleInRegionError = []
    MCSampleInAllRegions = RooArgSet()
    for ireg, region in enumerate(regionList):
      MCSampleInRegion = getPdfInRegions(w,sample,region)
      #MCSampleInRegion = Util.GetComponent(w,sample,region,exactRegionNames)
      MCSampleInRegionVal = 0.
      MCSampleInRegionError = 0.
      if not MCSampleInRegion==None:
        MCSampleInRegionVal = MCSampleInRegion.getVal()
        MCSampleInRegionError = Util.GetPropagatedError(MCSampleInRegion, resultBeforeFit, doAsym) 
        MCSampleInAllRegions.add(MCSampleInRegion)
      else:
        print " \n WARNING: sample=", sampleName, " non-existent (empty) in region=",region
      nMCSampleInRegionVal.append(MCSampleInRegionVal)
      nMCSampleInRegionError.append(MCSampleInRegionError)
    if showSum:
      MCSampleSumInAllRegions = RooAddition( (sampleName+"_AllRegions_MC"), (sampleName+"_AllRegions_MC"), RooArgList(MCSampleInAllRegions))
      nMCSampleSumVal = MCSampleSumInAllRegions.getVal()
      nMCSampleSumError = Util.GetPropagatedError(MCSampleSumInAllRegions, resultBeforeFit, doAsym)
      nMCSampleInRegionVal.append(nMCSampleSumVal)
      nMCSampleInRegionError.append(nMCSampleSumError)
    tablenumbers['MC_exp_events_'+sampleName] = nMCSampleInRegionVal
    tablenumbers['MC_exp_err_'+sampleName] = nMCSampleInRegionError

    #  sorted(tablenumbers, key=lambda sample: sample[1])   # sort by age
  map_listofkeys = tablenumbers.keys()
  map_listofkeys.sort()
  
  for name in map_listofkeys:
    if tablenumbers.has_key(name) :
      print name, ": ", tablenumbers[name]
      
  ###
  return tablenumbers
Пример #3
0
def latexfitresults(filename,
                    namemap,
                    region='3jL',
                    sample='',
                    resultName="RooExpandedFitResult_afterFit",
                    dataname='obsData',
                    doAsym=True,
                    SRName=""):
    """
  Method-1: set all parameters constant, except for the one you're interested in, 
           calculate the systematic/error propagated due to that parameter

  @param filename The filename containing afterFit workspace
  @param namemap Defines whether any systematics need to be grouped in calculation (by default not defined, hence each parameter gets used one by one)
  @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 dataname The name of dataset (default='obsData')
  @param doAsym Calculates asymmetric errors taken from MINOS (default=True)
"""
    """
  pick up workspace from file
  """
    workspacename = 'w'
    w = Util.GetWorkspaceFromFile(filename, workspacename)
    if w == None:
        print "ERROR : Cannot open workspace : ", workspacename
        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)
    """
  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)
    """
  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)
    """
  retrieve and save number of observed (=data) events in region
  """
    nobsRegion = 0.
    if dataRegion:
        nobsRegion = dataRegion.sumEntries()
    else:
        print " ERROR : dataset-category dataRegion 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 = getPdfInRegions(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
    """
  MakePlots
  """
    makeNicePlots(result, w, SRName)
    """
  calculate error per (floating) parameter in fitresult
  get a list of floating parameters to loop over
  """
    fpf = result.floatParsFinal()
    """
  set all floating parameters constant
  """
    for idx in range(fpf.getSize()):
        parname = fpf[idx].GetName()
        par = w.var(parname)
        par.setConstant()
    """
  if several systematatic/parameters are pre-defined in namemap, they will be floated together
  or in other words, one will get the error due to all pre-defined systematics
  """
    """
  else, float each parameter one by one and calculate the error due to it
  """
    if len(namemap) > 0:
        for key in namemap.keys():
            print namemap[key]
            for parname in namemap[key]:
                par = w.var(parname)
                par.setConstant(False)
                pass
            sysError = Util.GetPropagatedError(pdfInRegion, result, doAsym)
            regSys['syserr_' + key] = sysError
            for idx in range(fpf.getSize()):
                parname = fpf[idx].GetName()
                par = w.var(parname)
                par.setConstant()
                pass
    else:
        for idx in range(fpf.getSize()):
            parname = fpf[idx].GetName()
            par = w.var(parname)
            par.setConstant(False)
            sysError = Util.GetPropagatedError(pdfInRegion, result, doAsym)
            regSys['syserr_' + parname] = sysError
            par.setConstant()
            print parname, par.getVal(), par.getError()

    return regSys
Пример #4
0
def latexfitresults(filename,
                    regionList,
                    sampleList,
                    dataname='obsData',
                    showSum=False,
                    doAsym=True,
                    blinded=False,
                    splitBins=False):
    """
  Calculate before/after-fit yields in all channels given
  
  @param filename The filename containing afterFit workspace
  @param regionList A list of regions to be considered
  @param sampleList A list of samples to be considered
  @param dataname The name of dataset (default='obsData')
  @param showSum Calculates sum of all regions if set to true (default=False)
  @param doAsym Calculates asymmetric errors taken from MINOS (default=True)
  @param blinded Observed event count will not be shown if set to True (default=False)
  @param splitBins Calculates bin-by-bin yields for all regions if set to True (default=False)
  """
    """
  pick up workspace from file
  """
    workspacename = 'w'
    w = Util.GetWorkspaceFromFile(filename, 'w')
    if w == None:
        print "ERROR : Cannot open workspace : ", workspacename
        sys.exit(1)
    """
  pick up after-fit RooExpandedFitResult from workspace
  """
    resultAfterFit = w.obj('RooExpandedFitResult_afterFit')
    if resultAfterFit == None:
        print "ERROR : Cannot open fit result after fit RooExpandedFitResult_afterFit"
        sys.exit(1)
    """
  pick up before-fit RooExpandedFitResult from workspace
  """
    resultBeforeFit = w.obj('RooExpandedFitResult_beforeFit')
    if resultBeforeFit == None:
        print "ERROR : Cannot open fit result before fit RooExpandedFitResult_beforeFit"
        sys.exit(1)
    """
  pick up dataset from workspace
  """
    data_set = w.data(dataname)
    if data_set == None:
        print "ERROR : Cannot open dataset : ", "data_set" + suffix
        sys.exit(1)
    """
  pick up channel category (RooCategory) from workspace
  """
    regionCat = w.obj("channelCat")
    if not blinded:
        data_set.table(regionCat).Print("v")
    """
  find full (long) name list of regions (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50)
  """
    regionFullNameList = [
        Util.GetFullRegionName(regionCat, region) for region in regionList
    ]
    """
  load afterFit workspace snapshot (=set all parameters to values after fit)
  """
    snapshot = 'snapshot_paramsVals_RooExpandedFitResult_afterFit'
    w.loadSnapshot(snapshot)

    if not w.loadSnapshot(snapshot):
        print "ERROR : Cannot load snapshot : ", snapshot
        sys.exit(1)
    """
  define set, for all names/yields to be saved in
  """
    tablenumbers = {}
    """
  if showSum=True define names for sum of all regions and add to regionList
  """
    sumName = ""
    for index, reg in enumerate(regionList):
        if index == 0:
            sumName = reg
        else:
            sumName = sumName + " + " + reg

    regionListWithSum = list(regionList)
    if showSum:
        regionListWithSum.append(sumName)

    tablenumbers['names'] = regionListWithSum
    """
  make a list of channelCat calls for every region
  """
    regionCatList = [
        'channelCat==channelCat::' + region.Data()
        for region in regionFullNameList
    ]
    """
  retrieve number of observed (=data) events per region
  """
    regionDatasetList = [
        data_set.reduce(regioncat) for regioncat in regionCatList
    ]
    for index, data in enumerate(regionDatasetList):
        data.SetName("data_" + regionList[index])
        data.SetTitle("data_" + regionList[index])

    nobs_regionList = [data.sumEntries() for data in regionDatasetList]
    """
  if showSum=True calculate the total number of observed events in all regions  
  """
    sumNobs = 0.
    for nobs in nobs_regionList:
        sumNobs += nobs
    if showSum:
        nobs_regionList.append(sumNobs)
    tablenumbers['nobs'] = nobs_regionList
    """
  FROM HERE ON OUT WE CALCULATE THE FITTED NUMBER OF EVENTS __AFTER__ THE FIT
  """
    """
  get a list of pdf's and variables per region
  """
    pdfinRegionList = [Util.GetRegionPdf(w, region) for region in regionList]
    varinRegionList = [Util.GetRegionVar(w, region) for region in regionList]
    """
  if splitBins=True get the list of Nbins, binMax and binMin; make a list of new region names for each bin
  """
    varNbinsInRegionList = []
    varBinLowInRegionList = []
    varBinHighInRegionList = []
    rangeNameBinsInRegionList = []
    if splitBins:
        varNbinsInRegionList = [
            Util.GetRegionVar(w, region).getBinning().numBins()
            for region in regionList
        ]
        varBinLowInRegionList = [[
            Util.GetRegionVar(w, region).getBinning(
                (region + "binning")).binLow(ibin)
            for ibin in range(0, varNbinsInRegionList[idx])
        ] for idx, region in enumerate(regionList)]
        varBinHighInRegionList = [[
            Util.GetRegionVar(w, region).getBinning(
                (region + "binning")).binHigh(ibin)
            for ibin in range(0, varNbinsInRegionList[idx])
        ] for idx, region in enumerate(regionList)]
        rangeNameBinsInRegionList = [[
            regionList[idx] + "_bin" + str(ibin)
            for ibin in range(0, varNbinsInRegionList[idx])
        ] for idx, region in enumerate(regionList)]
        for index, region in enumerate(regionList):
            if varNbinsInRegionList[index] == 1:
                print " \n YieldsTable.py: WARNING: you have called -P (= per-bin yields) but this region ", region, " has only 1 bin \n"
    """
  if splitBins=True reshuffle the regionName list; each region name is followed by names of each bin (i.e. regionNameList=['SR3J','SR3J_bin1','SR3j_bin2','SR4J','SR4J_bin1'])
  """
    regionListWithBins = []
    if splitBins:
        for index, region in enumerate(regionList):
            regionListWithBins.append(region)
            for ibin in range(0, varNbinsInRegionList[index]):
                regionListWithBins.append(
                    rangeNameBinsInRegionList[index][ibin])
        tablenumbers['names'] = regionListWithBins
    """
  calculate number of observed(=data) events per bin
  """
    nobs_regionListWithBins = []
    if splitBins:
        binFuncInRegionList = [
            RooBinningCategory("bin_" + region, "bin_" + region,
                               varinRegionList[index])
            for index, region in enumerate(regionList)
        ]
        for index, data in enumerate(regionDatasetList):
            data.addColumn(binFuncInRegionList[index])
            if not blinded:
                data.table(binFuncInRegionList[index]).Print("v")
            nobs_regionListWithBins.append(data.sumEntries())
            for ibin in range(0, varNbinsInRegionList[index]):
                nobs_regionListWithBins.append(
                    (data.reduce(binFuncInRegionList[index].GetName() + "==" +
                                 binFuncInRegionList[index].GetName() + "::" +
                                 varinRegionList[index].GetName() + "_bin" +
                                 str(ibin))).sumEntries())

        tablenumbers['nobs'] = nobs_regionListWithBins
    """
  if blinded=True, set all numbers of observed events to -1
  """
    if blinded:
        for index, nobs in enumerate(nobs_regionListWithBins):
            nobs_regionListWithBins[index] = -1
        tablenumbers['nobs'] = nobs_regionListWithBins
    """
  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
  """
    rrspdfinRegionList = []
    for index, pdf in enumerate(pdfinRegionList):
        prodList = pdf.pdfList()
        foundRRS = 0
        for idx in range(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt = prodList[idx].createIntegral(
                    RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(rrspdfInt)
                if splitBins:
                    origMin = varinRegionList[index].getMin()
                    origMax = varinRegionList[index].getMax()
                    for ibin in range(0, varNbinsInRegionList[index]):
                        rangeName = rangeNameBinsInRegionList[index][ibin]
                        varinRegionList[index].setRange(
                            rangeName, varBinLowInRegionList[index][ibin],
                            varBinHighInRegionList[index][ibin])
                        rrspdfInt = prodList[idx].createIntegral(
                            RooArgSet(varinRegionList[index]), rangeName)
                        rrspdfinRegionList.append(rrspdfInt)
                    varinRegionList[index].setRange(origMin, origMax)
                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")
    """
  calculate total pdf number of fitted events and error
  """
    nFittedInRegionList = [
        pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)
    ]
    pdfFittedErrInRegionList = [
        Util.GetPropagatedError(pdf, resultAfterFit, doAsym)
        for pdf in rrspdfinRegionList
    ]
    """
  if showSum=True calculate the total number of fitted events in all regions  
  """
    if showSum:
        pdfInAllRegions = RooArgSet()
        for index, pdf in enumerate(rrspdfinRegionList):
            pdfInAllRegions.add(pdf)
        pdfSumInAllRegions = RooAddition("pdf_AllRegions_AFTER",
                                         "pdf_AllRegions_AFTER",
                                         RooArgList(pdfInAllRegions))
        nPdfSumVal = pdfSumInAllRegions.getVal()
        nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions,
                                               resultAfterFit, doAsym)
        nFittedInRegionList.append(nPdfSumVal)
        pdfFittedErrInRegionList.append(nPdfSumError)

    tablenumbers['TOTAL_FITTED_bkg_events'] = nFittedInRegionList
    tablenumbers['TOTAL_FITTED_bkg_events_err'] = pdfFittedErrInRegionList
    """
  calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
  """
    for isam, sample in enumerate(sampleList):
        sampleName = getName(sample)
        nSampleInRegionVal = []
        nSampleInRegionError = []
        sampleInAllRegions = RooArgSet()
        for ireg, region in enumerate(regionList):
            sampleInRegion = getPdfInRegions(w, sample, region)
            sampleInRegionVal = 0.
            sampleInRegionError = 0.
            if not sampleInRegion == None:
                sampleInRegionVal = sampleInRegion.getVal()
                sampleInRegionError = Util.GetPropagatedError(
                    sampleInRegion, resultAfterFit, doAsym)
                sampleInAllRegions.add(sampleInRegion)
            else:
                print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region =", region, "\n"
            nSampleInRegionVal.append(sampleInRegionVal)
            nSampleInRegionError.append(sampleInRegionError)
            """
      if splitBins=True calculate numbers of fitted events plus error per bin      
      """
            if splitBins:
                origMin = varinRegionList[ireg].getMin()
                origMax = varinRegionList[ireg].getMax()
                for ibin in range(0, varNbinsInRegionList[ireg]):
                    rangeName = rangeNameBinsInRegionList[ireg][ibin]
                    sampleInRegion = getPdfInRegionsWithRangeName(
                        w, sample, region, rangeName)
                    sampleInRegionVal = 0.
                    sampleInRegionError = 0.
                    if not sampleInRegion == None:
                        varinRegionList[ireg].setRange(
                            rangeName, varBinLowInRegionList[ireg][ibin],
                            varBinHighInRegionList[ireg][ibin])
                        sampleInRegionVal = sampleInRegion.getVal()
                        sampleInRegionError = Util.GetPropagatedError(
                            sampleInRegion, resultAfterFit, doAsym)
                    else:
                        print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region=", region, " bin=", ibin, " \n"
                    nSampleInRegionVal.append(sampleInRegionVal)
                    nSampleInRegionError.append(sampleInRegionError)

                varinRegionList[ireg].setRange(origMin, origMax)
        """
    if showSum=True calculate the total number of fitted events in all regions  
    """
        if showSum:
            sampleSumInAllRegions = RooAddition(
                (sampleName + "_AllRegions_FITTED"),
                (sampleName + "_AllRegions_FITTED"),
                RooArgList(sampleInAllRegions))
            nSampleSumVal = sampleSumInAllRegions.getVal()
            nSampleSumError = Util.GetPropagatedError(sampleSumInAllRegions,
                                                      resultAfterFit, doAsym)
            nSampleInRegionVal.append(nSampleSumVal)
            nSampleInRegionError.append(nSampleSumError)
        tablenumbers['Fitted_events_' + sampleName] = nSampleInRegionVal
        tablenumbers['Fitted_err_' + sampleName] = nSampleInRegionError

    print "\n starting BEFORE-FIT calculations \n"
    """
  FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS __BEFORRE__ THE FIT
  """
    """
  load beforeFit workspace snapshot (=set all parameters to values before fit)
  """
    w.loadSnapshot('snapshot_paramsVals_RooExpandedFitResult_beforeFit')
    """
  check if any of the initial scaling factors is != 1
  """
    _result = w.obj('RooExpandedFitResult_beforeFit')
    _muFacs = _result.floatParsFinal()

    for i in range(len(_muFacs)):
        if "mu_" in _muFacs[i].GetName() and _muFacs[i].getVal() != 1.0:
            print " \n WARNING: scaling factor %s != 1.0 (%g) expected MC yield WILL BE WRONG!" % (
                _muFacs[i].GetName(), _muFacs[i].getVal())
    """
  get a list of pdf's and variables per region
  """
    pdfinRegionList = [Util.GetRegionPdf(w, region) for region in regionList]
    varinRegionList = [Util.GetRegionVar(w, region) for region in regionList]
    """
  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
  """
    rrspdfinRegionList = []
    for index, pdf in enumerate(pdfinRegionList):
        prodList = pdf.pdfList()
        foundRRS = 0
        for idx in range(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt = prodList[idx].createIntegral(
                    RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(rrspdfInt)
                if splitBins:
                    origMin = varinRegionList[index].getMin()
                    origMax = varinRegionList[index].getMax()
                    for ibin in range(0, varNbinsInRegionList[index]):
                        rangeName = rangeNameBinsInRegionList[index][ibin]
                        varinRegionList[index].setRange(
                            rangeName, varBinLowInRegionList[index][ibin],
                            varBinHighInRegionList[index][ibin])
                        rrspdfInt = prodList[idx].createIntegral(
                            RooArgSet(varinRegionList[index]), rangeName)
                        rrspdfinRegionList.append(rrspdfInt)
                    varinRegionList[index].setRange(origMin, origMax)
                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")
    """
  calculate total pdf number of expected events and error
  """
    nExpInRegionList = [
        pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)
    ]
    pdfExpErrInRegionList = [
        Util.GetPropagatedError(pdf, resultBeforeFit, doAsym)
        for pdf in rrspdfinRegionList
    ]
    """
  if showSum=True calculate the total number of expected events in all regions  
  """
    if showSum:
        pdfInAllRegions = RooArgSet()
        for index, pdf in enumerate(rrspdfinRegionList):
            pdfInAllRegions.add(pdf)
        pdfSumInAllRegions = RooAddition("pdf_AllRegions_BEFORE",
                                         "pdf_AllRegions_BEFORE",
                                         RooArgList(pdfInAllRegions))
        nPdfSumVal = pdfSumInAllRegions.getVal()
        nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions,
                                               resultBeforeFit, doAsym)
        nExpInRegionList.append(nPdfSumVal)
        pdfExpErrInRegionList.append(nPdfSumError)

    tablenumbers['TOTAL_MC_EXP_BKG_events'] = nExpInRegionList
    tablenumbers['TOTAL_MC_EXP_BKG_err'] = pdfExpErrInRegionList
    """
  calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
  """
    for isam, sample in enumerate(sampleList):
        sampleName = getName(sample)
        nMCSampleInRegionVal = []
        nMCSampleInRegionError = []
        MCSampleInAllRegions = RooArgSet()
        for ireg, region in enumerate(regionList):
            MCSampleInRegion = getPdfInRegions(w, sample, region)
            MCSampleInRegionVal = 0.
            MCSampleInRegionError = 0.
            if not MCSampleInRegion == None:
                MCSampleInRegionVal = MCSampleInRegion.getVal()
                MCSampleInRegionError = Util.GetPropagatedError(
                    MCSampleInRegion, resultBeforeFit, doAsym)
                MCSampleInAllRegions.add(MCSampleInRegion)
            else:
                print " \n WARNING: sample=", sampleName, " non-existent (empty) in region=", region
            nMCSampleInRegionVal.append(MCSampleInRegionVal)
            nMCSampleInRegionError.append(MCSampleInRegionError)
            """
      if splitBins=True calculate numbers of fitted events plus error per bin      
      """
            if splitBins:
                origMin = varinRegionList[ireg].getMin()
                origMax = varinRegionList[ireg].getMax()
                for ibin in range(0, varNbinsInRegionList[ireg]):
                    rangeName = rangeNameBinsInRegionList[ireg][ibin]
                    MCSampleInRegion = getPdfInRegionsWithRangeName(
                        w, sample, region, rangeName)
                    MCSampleInRegionVal = 0.
                    MCSampleInRegionError = 0.
                    if not MCSampleInRegion == None:
                        varinRegionList[ireg].setRange(
                            rangeName, varBinLowInRegionList[ireg][ibin],
                            varBinHighInRegionList[ireg][ibin])
                        MCSampleInRegionVal = MCSampleInRegion.getVal()
                        MCSampleInRegionError = Util.GetPropagatedError(
                            MCSampleInRegion, resultBeforeFit, doAsym)
                    else:
                        print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region=", region, " bin=", ibin, " \n"
                    nMCSampleInRegionVal.append(MCSampleInRegionVal)
                    nMCSampleInRegionError.append(MCSampleInRegionError)

                varinRegionList[ireg].setRange(origMin, origMax)
        """
    if showSum=True calculate the total number of fitted events in all regions  
    """
        if showSum:
            MCSampleSumInAllRegions = RooAddition(
                (sampleName + "_AllRegions_MC"),
                (sampleName + "_AllRegions_MC"),
                RooArgList(MCSampleInAllRegions))
            nMCSampleSumVal = MCSampleSumInAllRegions.getVal()
            nMCSampleSumError = Util.GetPropagatedError(
                MCSampleSumInAllRegions, resultBeforeFit, doAsym)
            nMCSampleInRegionVal.append(nMCSampleSumVal)
            nMCSampleInRegionError.append(nMCSampleSumError)
        tablenumbers['MC_exp_events_' + sampleName] = nMCSampleInRegionVal
        tablenumbers['MC_exp_err_' + sampleName] = nMCSampleInRegionError
    """
  sort the tablenumbers set
  """
    map_listofkeys = tablenumbers.keys()
    map_listofkeys.sort()
    """
  print the sorted tablenumbers set
  """
    for name in map_listofkeys:
        if tablenumbers.has_key(name):
            print name, ": ", tablenumbers[name]

    return tablenumbers
def latexfitresults(filename,regionList,sampleList,dataname='obsData',showSum=False, doAsym=True, blinded=False, splitBins=False):
  """
  Calculate before/after-fit yields in all channels given

  @param filename The filename containing afterFit workspace
  @param regionList A list of regions to be considered
  @param sampleList A list of samples to be considered
  @param dataname The name of dataset (default='obsData')
  @param showSum Calculates sum of all regions if set to true (default=False)
  @param doAsym Calculates asymmetric errors taken from MINOS (default=True)
  @param blinded Observed event count will not be shown if set to True (default=False)
  @param splitBins Calculates bin-by-bin yields for all regions if set to True (default=False)
  """

  """
  pick up workspace from file
  """
  workspacename = 'w'
  w = Util.GetWorkspaceFromFile(filename,'w')
  if w==None:
    print "ERROR : Cannot open workspace : ", workspacename
    sys.exit(1)

  """
  pick up after-fit RooExpandedFitResult from workspace
  """
  resultAfterFit = w.obj('RooExpandedFitResult_afterFit')
  if resultAfterFit==None:
    print "ERROR : Cannot open fit result after fit RooExpandedFitResult_afterFit"
    sys.exit(1)

  """
  pick up before-fit RooExpandedFitResult from workspace
  """
  resultBeforeFit = w.obj('RooExpandedFitResult_beforeFit')
  if resultBeforeFit==None:
    print "ERROR : Cannot open fit result before fit RooExpandedFitResult_beforeFit"
    sys.exit(1)

  """
  pick up dataset from workspace
  """
  data_set = w.data(dataname)
  if data_set==None:
    print "ERROR : Cannot open dataset : ", "data_set"+suffix
    sys.exit(1)

  """
  pick up channel category (RooCategory) from workspace
  """
  regionCat = w.obj("channelCat")
  if not blinded:
    data_set.table(regionCat).Print("v")

  """
  find full (long) name list of regions (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50)
  """
  regionFullNameList = [ Util.GetFullRegionName(regionCat, region) for region in regionList]


  """
  load afterFit workspace snapshot (=set all parameters to values after fit)
  """
  snapshot =  'snapshot_paramsVals_RooExpandedFitResult_afterFit'
  w.loadSnapshot(snapshot)

  if not w.loadSnapshot(snapshot):
    print "ERROR : Cannot load snapshot : ", snapshot
    sys.exit(1)

  """
  define set, for all names/yields to be saved in
  """
  tablenumbers = {}

  """
  if showSum=True define names for sum of all regions and add to regionList
  """
  sumName = ""
  for index, reg in enumerate(regionList):
    if index == 0:
      sumName = reg
    else:
      sumName = sumName + " + " + reg

  regionListWithSum = list(regionList)
  if showSum:
    regionListWithSum.append(sumName)

  tablenumbers['names'] = regionListWithSum

  """
  make a list of channelCat calls for every region
  """
  regionCatList = [ 'channelCat==channelCat::' +region.Data() for region in regionFullNameList]

  """
  retrieve number of observed (=data) events per region
  """
  print regionCatList
  srindex = regionFullNameList.index("SR_cuts")
  regionDatasetList = [data_set.reduce(regioncat) for regioncat in regionCatList]

  for index, data in enumerate(regionDatasetList):
    print "data," , data, data.GetName()
    data.SetName("data_" + regionList[index])
    data.SetTitle("data_" + regionList[index])

  nobs_regionList = [ data.sumEntries() for data in regionDatasetList]
  if blinded :  nobs_regionList[srindex] = -1
  """
  if showSum=True calculate the total number of observed events in all regions
  """
  sumNobs = 0.
  for nobs in nobs_regionList:
    sumNobs += nobs
  if showSum:
    nobs_regionList.append(sumNobs)
  tablenumbers['nobs'] = nobs_regionList


  """
  FROM HERE ON OUT WE CALCULATE THE FITTED NUMBER OF EVENTS __AFTER__ THE FIT
  """

  """
  get a list of pdf's and variables per region
  """
  pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in regionList]
  varinRegionList =  [ Util.GetRegionVar(w, region) for region in regionList]

  """
  if splitBins=True get the list of Nbins, binMax and binMin; make a list of new region names for each bin
  """
  varNbinsInRegionList =  []
  varBinLowInRegionList = []
  varBinHighInRegionList =  []
  rangeNameBinsInRegionList = []
  if splitBins:
    varNbinsInRegionList = [Util.GetRegionVar(w, region).getBinning().numBins() for region in regionList]
    varBinLowInRegionList = [[Util.GetRegionVar(w, region).getBinning((region+"binning")).binLow(ibin) for ibin in range(0, varNbinsInRegionList[idx]) ] for idx,region in enumerate(regionList)]
    varBinHighInRegionList = [[Util.GetRegionVar(w, region).getBinning((region+"binning")).binHigh(ibin) for ibin in range(0, varNbinsInRegionList[idx]) ] for idx,region in enumerate(regionList)]
    rangeNameBinsInRegionList = [[regionList[idx]+"_bin"+str(ibin) for ibin in range(0, varNbinsInRegionList[idx]) ] for idx,region in enumerate(regionList)]
    for index,region in enumerate(regionList):
      if varNbinsInRegionList[index]==1:
        print " \n YieldsTable.py: WARNING: you have called -P (= per-bin yields) but this region ", region, " has only 1 bin \n"



  """
  if splitBins=True reshuffle the regionName list; each region name is followed by names of each bin (i.e. regionNameList=['SR3J','SR3J_bin1','SR3j_bin2','SR4J','SR4J_bin1'])
  """
  regionListWithBins = []
  if splitBins:
    for index,region in enumerate(regionList):
      regionListWithBins.append(region)
      for ibin in range(0,varNbinsInRegionList[index]):
        regionListWithBins.append(rangeNameBinsInRegionList[index][ibin])
    tablenumbers['names'] = regionListWithBins


  """
  calculate number of observed(=data) events per bin
  """
  nobs_regionListWithBins = []
  if splitBins:
    binFuncInRegionList = [RooBinningCategory("bin_"+region,"bin_"+region,varinRegionList[index]) for index,region in enumerate(regionList)]
    for index, data in enumerate(regionDatasetList):
      data.addColumn(binFuncInRegionList[index])
      if not blinded:
        data.table(binFuncInRegionList[index]).Print("v")
      nobs_regionListWithBins.append(data.sumEntries())
      for ibin in range(0,varNbinsInRegionList[index]):
        nobs_regionListWithBins.append((data.reduce(binFuncInRegionList[index].GetName()+"=="+binFuncInRegionList[index].GetName()+"::"+varinRegionList[index].GetName()+"_bin"+str(ibin))).sumEntries())

    tablenumbers['nobs'] = nobs_regionListWithBins

  """
  if blinded=True, set all numbers of observed events to -1
  """
  if blinded and splitBins:
    for index, nobs in enumerate(nobs_regionListWithBins):
      nobs_regionListWithBins[index] = -1
    tablenumbers['nobs'] = nobs_regionListWithBins


  """
  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
  """
  rrspdfinRegionList = []
  for index,pdf in enumerate(pdfinRegionList):
    prodList = pdf.pdfList()
    foundRRS = 0
    for idx in range(prodList.getSize()):
      if prodList[idx].InheritsFrom("RooRealSumPdf"):
        rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]))
        rrspdfinRegionList.append(rrspdfInt)
        if splitBins:
          origMin = varinRegionList[index].getMin()
          origMax = varinRegionList[index].getMax()
          for ibin in range(0,varNbinsInRegionList[index]):
            rangeName = rangeNameBinsInRegionList[index][ibin]
            varinRegionList[index].setRange(rangeName,varBinLowInRegionList[index][ibin],varBinHighInRegionList[index][ibin])
            rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]),rangeName)
            rrspdfinRegionList.append(rrspdfInt)
          varinRegionList[index].setRange(origMin,origMax)
        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")

  """
  calculate total pdf number of fitted events and error
  """
  nFittedInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
  pdfFittedErrInRegionList = [ Util.GetPropagatedError(pdf, resultAfterFit, doAsym) for pdf in rrspdfinRegionList]


  """
  if showSum=True calculate the total number of fitted events in all regions
  """
  if showSum:
    pdfInAllRegions = RooArgSet()
    for index, pdf in enumerate(rrspdfinRegionList):
      pdfInAllRegions.add(pdf)
    pdfSumInAllRegions = RooAddition( "pdf_AllRegions_AFTER", "pdf_AllRegions_AFTER", RooArgList(pdfInAllRegions))
    nPdfSumVal = pdfSumInAllRegions.getVal()
    nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions, resultAfterFit, doAsym)
    nFittedInRegionList.append(nPdfSumVal)
    pdfFittedErrInRegionList.append(nPdfSumError)

  tablenumbers['TOTAL_FITTED_bkg_events']    =  nFittedInRegionList
  tablenumbers['TOTAL_FITTED_bkg_events_err']    =  pdfFittedErrInRegionList

  """
  calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
  """
  for isam, sample in enumerate(sampleList):
    sampleName=getName(sample)
    nSampleInRegionVal = []
    nSampleInRegionError = []
    sampleInAllRegions = RooArgSet()
    for ireg, region in enumerate(regionList):
      sampleInRegion=getPdfInRegions(w,sample,region)
      sampleInRegionVal = 0.
      sampleInRegionError = 0.
      if not sampleInRegion==None:
        sampleInRegionVal = sampleInRegion.getVal()
        sampleInRegionError = Util.GetPropagatedError(sampleInRegion, resultAfterFit, doAsym)
        sampleInAllRegions.add(sampleInRegion)
      else:
        print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region =",region, "\n"
      nSampleInRegionVal.append(sampleInRegionVal)
      nSampleInRegionError.append(sampleInRegionError)

      """
      if splitBins=True calculate numbers of fitted events plus error per bin
      """
      if splitBins:
        origMin = varinRegionList[ireg].getMin()
        origMax = varinRegionList[ireg].getMax()
        for ibin in range(0,varNbinsInRegionList[ireg]):
          rangeName = rangeNameBinsInRegionList[ireg][ibin]
          sampleInRegion=getPdfInRegionsWithRangeName(w,sample,region,rangeName)
          sampleInRegionVal = 0.
          sampleInRegionError = 0.
          if not sampleInRegion==None:
            varinRegionList[ireg].setRange(rangeName,varBinLowInRegionList[ireg][ibin],varBinHighInRegionList[ireg][ibin])
            sampleInRegionVal = sampleInRegion.getVal()
            sampleInRegionError = Util.GetPropagatedError(sampleInRegion, resultAfterFit, doAsym)
          else:
            print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region=",region, " bin=",ibin, " \n"
          nSampleInRegionVal.append(sampleInRegionVal)
          nSampleInRegionError.append(sampleInRegionError)

        varinRegionList[ireg].setRange(origMin,origMax)

    """
    if showSum=True calculate the total number of fitted events in all regions
    """
    if showSum:
      sampleSumInAllRegions = RooAddition( (sampleName+"_AllRegions_FITTED"), (sampleName+"_AllRegions_FITTED"), RooArgList(sampleInAllRegions))
      nSampleSumVal = sampleSumInAllRegions.getVal()
      nSampleSumError = Util.GetPropagatedError(sampleSumInAllRegions, resultAfterFit, doAsym)
      nSampleInRegionVal.append(nSampleSumVal)
      nSampleInRegionError.append(nSampleSumError)
    tablenumbers['Fitted_events_'+sampleName]   = nSampleInRegionVal
    tablenumbers['Fitted_err_'+sampleName]   = nSampleInRegionError



  print "\n starting BEFORE-FIT calculations \n"
  """
  FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS __BEFORRE__ THE FIT
  """

  """
  load beforeFit workspace snapshot (=set all parameters to values before fit)
  """
  w.loadSnapshot('snapshot_paramsVals_RooExpandedFitResult_beforeFit')

  """
  check if any of the initial scaling factors is != 1
  """
  _result = w.obj('RooExpandedFitResult_beforeFit')
  _muFacs = _result.floatParsFinal()

  for i in range(len(_muFacs)):
    if "mu_" in _muFacs[i].GetName() and _muFacs[i].getVal() != 1.0:
      print  " \n WARNING: scaling factor %s != 1.0 (%g) expected MC yield WILL BE WRONG!" % (_muFacs[i].GetName(), _muFacs[i].getVal())

  """
  get a list of pdf's and variables per region
  """
  pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in regionList]
  varinRegionList =  [ Util.GetRegionVar(w, region) for region in regionList]

  """
  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
  """
  rrspdfinRegionList = []
  for index,pdf in enumerate(pdfinRegionList):
    prodList = pdf.pdfList()
    foundRRS = 0
    for idx in range(prodList.getSize()):
      if prodList[idx].InheritsFrom("RooRealSumPdf"):
        rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]))
        rrspdfinRegionList.append(rrspdfInt)
        if splitBins:
          origMin = varinRegionList[index].getMin()
          origMax = varinRegionList[index].getMax()
          for ibin in range(0,varNbinsInRegionList[index]):
            rangeName = rangeNameBinsInRegionList[index][ibin]
            varinRegionList[index].setRange(rangeName,varBinLowInRegionList[index][ibin],varBinHighInRegionList[index][ibin])
            rrspdfInt =  prodList[idx].createIntegral(RooArgSet(varinRegionList[index]),rangeName)
            rrspdfinRegionList.append(rrspdfInt)
          varinRegionList[index].setRange(origMin,origMax)
        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")

  """
  calculate total pdf number of expected events and error
  """
  nExpInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
  pdfExpErrInRegionList = [ Util.GetPropagatedError(pdf, resultBeforeFit, doAsym)  for pdf in rrspdfinRegionList]

  """
  if showSum=True calculate the total number of expected events in all regions
  """
  if showSum:
    pdfInAllRegions = RooArgSet()
    for index, pdf in enumerate(rrspdfinRegionList):
      pdfInAllRegions.add(pdf)
    pdfSumInAllRegions = RooAddition( "pdf_AllRegions_BEFORE", "pdf_AllRegions_BEFORE", RooArgList(pdfInAllRegions))
    nPdfSumVal = pdfSumInAllRegions.getVal()
    nPdfSumError = Util.GetPropagatedError(pdfSumInAllRegions, resultBeforeFit, doAsym)
    nExpInRegionList.append(nPdfSumVal)
    pdfExpErrInRegionList.append(nPdfSumError)

  tablenumbers['TOTAL_MC_EXP_BKG_events']    =  nExpInRegionList
  tablenumbers['TOTAL_MC_EXP_BKG_err']    =  pdfExpErrInRegionList

  """
  calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
  """
  for isam, sample in enumerate(sampleList):
    sampleName=getName(sample)
    nMCSampleInRegionVal = []
    nMCSampleInRegionError = []
    MCSampleInAllRegions = RooArgSet()
    for ireg, region in enumerate(regionList):
      MCSampleInRegion = getPdfInRegions(w,sample,region)
      MCSampleInRegionVal = 0.
      MCSampleInRegionError = 0.
      if not MCSampleInRegion==None:
        MCSampleInRegionVal = MCSampleInRegion.getVal()
        MCSampleInRegionError = Util.GetPropagatedError(MCSampleInRegion, resultBeforeFit, doAsym)
        MCSampleInAllRegions.add(MCSampleInRegion)
      else:
        print " \n WARNING: sample=", sampleName, " non-existent (empty) in region=",region
      nMCSampleInRegionVal.append(MCSampleInRegionVal)
      nMCSampleInRegionError.append(MCSampleInRegionError)

      """
      if splitBins=True calculate numbers of fitted events plus error per bin
      """
      if splitBins:
        origMin = varinRegionList[ireg].getMin()
        origMax = varinRegionList[ireg].getMax()
        for ibin in range(0,varNbinsInRegionList[ireg]):
          rangeName = rangeNameBinsInRegionList[ireg][ibin]
          MCSampleInRegion=getPdfInRegionsWithRangeName(w,sample,region,rangeName)
          MCSampleInRegionVal = 0.
          MCSampleInRegionError = 0.
          if not MCSampleInRegion==None:
            varinRegionList[ireg].setRange(rangeName,varBinLowInRegionList[ireg][ibin],varBinHighInRegionList[ireg][ibin])
            MCSampleInRegionVal = MCSampleInRegion.getVal()
            MCSampleInRegionError = Util.GetPropagatedError(MCSampleInRegion, resultBeforeFit, doAsym)
          else:
            print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region=",region, " bin=",ibin, " \n"
          nMCSampleInRegionVal.append(MCSampleInRegionVal)
          nMCSampleInRegionError.append(MCSampleInRegionError)

        varinRegionList[ireg].setRange(origMin,origMax)

    """
    if showSum=True calculate the total number of fitted events in all regions
    """
    if showSum:
      MCSampleSumInAllRegions = RooAddition( (sampleName+"_AllRegions_MC"), (sampleName+"_AllRegions_MC"), RooArgList(MCSampleInAllRegions))
      nMCSampleSumVal = MCSampleSumInAllRegions.getVal()
      nMCSampleSumError = Util.GetPropagatedError(MCSampleSumInAllRegions, resultBeforeFit, doAsym)
      nMCSampleInRegionVal.append(nMCSampleSumVal)
      nMCSampleInRegionError.append(nMCSampleSumError)
    tablenumbers['MC_exp_events_'+sampleName] = nMCSampleInRegionVal
    tablenumbers['MC_exp_err_'+sampleName] = nMCSampleInRegionError

  """
  sort the tablenumbers set
  """
  map_listofkeys = tablenumbers.keys()
  map_listofkeys.sort()

  """
  print the sorted tablenumbers set
  """
  for name in map_listofkeys:
    if tablenumbers.has_key(name) :
      print name, ": ", tablenumbers[name]

  return tablenumbers
Пример #6
0
def latexfitresults(filename, region, sample, resultName, dataname, doAsym):
    """
    Method: set all parameters constant, except for the one you're interested in,
    calculate the systematic/error propagated due to that parameter

    filename: The filename containing afterFit workspace
    resultname: The name of fit result (typically='RooExpandedFitResult_afterFit' or 'RooExpandedFitResult_beforeFit'
    region: The region to be used for systematics breakdown calculation
    sample: The sample to be used insted of total pdf (default='' not defined, hence total pdf used)
    dataname: The name of dataset (default='obsData')
    doAsym: Calculates asymmetric errors taken from MINOS (default=True)
    """

    #pick up workspace from file
    workspacename = 'w'
    w = Util.GetWorkspaceFromFile(filename,workspacename)
    if w is None:
        print "ERROR : Cannot open workspace:", workspacename
        sys.exit(1)

    #pickup RooExpandedFitResult from workspace with name resultName (either before or after fit)
    result = w.obj(resultName)
    if result is None:
        print "ERROR : Cannot open fit result", resultName
        sys.exit(1)

    # 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 is None:
        print "ERROR : Cannot open dataset: ", "data_set"
        sys.exit(1)

    #pick up channel category (RooCategory) from workspace
    region_cat = w.obj("channelCat")
    data_set.table(region_cat).Print("v");

    # find full (long) name list of region (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50)
    region_full_name = Util.GetFullRegionName(region_cat, region);

    # set a boolean whether we're looking at a sample or the full (multi-sample) pdf/model
    chosen_sample = bool(sample)

    # define regSys set, for all names/numbers to be saved in
    reg_sys = {}

    # define channelCat call for this region and reduce the dataset to this category/region
    region_cat_str = 'channelCat==channelCat::' + region_full_name.Data()
    data_region = data_set.reduce(region_cat_str)

    # retrieve and save number of observed (=data) events in region
    nobs_region = 0.
    if data_region:
        nobs_region = data_region.sumEntries()
    else:
        print " ERROR : dataset-category dataRegion not found"

    # if looking at a sample, there is no equivalent N_obs (only for the full model)
    if chosen_sample:
        reg_sys['sqrtnobsa'] = 0.
    else:
        reg_sys['sqrtnobsa'] = ROOT.TMath.Sqrt(nobs_region)

    # get the pdf for the total model or just for the sample in region
    if chosen_sample:
        pdf_in_region = getPdfInRegions(w, sample, region)
    else:
        raw_pdf_in_region = Util.GetRegionPdf(w, region)
        var_in_region =  Util.GetRegionVar(w, region)
        prod_list = raw_pdf_in_region.pdfList()

        foundRRS = 0
        for idx in xrange(prod_list.getSize()):
            if prod_list[idx].InheritsFrom("RooRealSumPdf"):
                rrspdf_int =  prod_list[idx].createIntegral(ROOT.RooArgSet(var_in_region));
                pdf_in_region = rrspdf_int
                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 pdf_in_region:
            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
    n_fitted_in_region = pdf_in_region.getVal()
    reg_sys['sqrtnfitted'] = ROOT.TMath.Sqrt(n_fitted_in_region)
    reg_sys['nfitted'] = n_fitted_in_region

    pdf_fitted_err_in_region = Util.GetPropagatedError(pdf_in_region, result, doAsym)
    reg_sys['totsyserr'] = pdf_fitted_err_in_region


    # calculate error per (floating) parameter in fitresult
    # get a list of floating parameters to loop over
    fpf = result.floatParsFinal()

    # set all floating parameters constant
    for idx in xrange(fpf.getSize()):
        parname = fpf[idx].GetName()
        par = w.var(parname)
        par.setConstant(True)

    for idx in xrange(fpf.getSize()):
        parname = fpf[idx].GetName()
        par = w.var(parname)
        par.setConstant(False)
        reg_sys['syserr_'+parname] =  Util.GetPropagatedError(pdf_in_region, result, doAsym)
        par.setConstant(True)

    return reg_sys
Пример #7
0
def latexfitresults( filename, namemap, region='3jL', sample='', resultName="RooExpandedFitResult_afterFit", dataname='obsData', doAsym=True):
  #Method-1: set all parameters constant, except for the one you're interested in, 
  #          calculate the error propagated due to that parameter

  workspacename = 'w'
  w = Util.GetWorkspaceFromFile(filename,workspacename)

  if w==None:
    print "ERROR : Cannot open workspace : ", workspacename
    sys.exit(1) 

  result = w.obj(resultName)
  if result==None:
    print "ERROR : Cannot open fit result ", resultName
    sys.exit(1)

  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);

  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 dataRegion not found"
    
  if chosenSample:
    regSys['sqrtnobsa'] = 0.
  else:
    regSys['sqrtnobsa'] = TMath.Sqrt(nobsRegion)

  ####

  if chosenSample:
    pdfInRegion=getPdfInRegions(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)
  regSys['nfitted'] = nFittedInRegion

  pdfFittedErrInRegion = Util.GetPropagatedError(pdfInRegion, result, doAsym) 
  regSys['totsyserr'] = pdfFittedErrInRegion


  # calculate error per parameter on  fitresult
  fpf = result.floatParsFinal() 
  
  # set all floating parameters constant
  for idx in range(fpf.getSize()):
    parname = fpf[idx].GetName()
    par = w.var(parname)
    par.setConstant()

  if len(namemap)>0: 
    #pre-defined systematics, optionally merged
    for key in namemap.keys():
      print namemap[key]
      #
      for parname in namemap[key]:
        par = w.var(parname)
        par.setConstant(False)
        pass
      #
      sysError  = Util.GetPropagatedError(pdfInRegion, result, doAsym)
      regSys['syserr_'+key] =  sysError
      #
      for idx in range(fpf.getSize()):
        parname = fpf[idx].GetName()
        par = w.var(parname)
        par.setConstant()
        pass
  else: 
    #all systematics, one-by-one
    for idx in range(fpf.getSize()):
      parname = fpf[idx].GetName()
      par = w.var(parname)
      par.setConstant(False)
      sysError  = Util.GetPropagatedError(pdfInRegion, result, doAsym)
      regSys['syserr_'+parname] =  sysError
      par.setConstant() 

  return regSys
Пример #8
0
def latexfitresults(filename, region_list, sample_list):

    f = ROOT.TFile.Open(filename)
    w = f.Get('w')

    if w is None:
        print "ERROR : Cannot open workspace : w"
        sys.exit(1)

    resultAfterFit = w.obj('RooExpandedFitResult_afterFit')
    if resultAfterFit is None:
        print "ERROR : Cannot open fit result after fit RooExpandedFitResult_afterFit"
        sys.exit(1)

    resultBeforeFit = w.obj('RooExpandedFitResult_beforeFit')
    if resultBeforeFit is None:
        print "ERROR : Cannot open fit result before fit RooExpandedFitResult_beforeFit"
        sys.exit(1)

    # pick up dataset from workspace
    data_set = w.data('obsData')
      
    # pick up channel category (RooCategory) from workspace
    regionCat = w.obj("channelCat")
    # if not blinded:
    #   data_set.table(regionCat).Print("v")

    # find full (long) name list of regions (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50)
    regionFullNameList = [ Util.GetFullRegionName(regionCat, region) for region in region_list ]

    # load afterFit workspace snapshot (=set all parameters to values after fit)
    snapshot =  'snapshot_paramsVals_RooExpandedFitResult_afterFit'
    w.loadSnapshot(snapshot)

    if not w.loadSnapshot(snapshot):
        print "ERROR : Cannot load snapshot : ", snapshot
        sys.exit(1)

    # define set, for all names/yields to be saved in
    tablenumbers = {}

    tablenumbers['names'] = region_list

    # make a list of channelCat calls for every region
    regionCatList = [ 'channelCat==channelCat::' + region.Data() for region in regionFullNameList]
  
    # retrieve number of observed (=data) events per region
    regionDatasetList = [data_set.reduce(regioncat) for regioncat in regionCatList]
    for index, data in enumerate(regionDatasetList):
        data.SetName("data_" + region_list[index])
        data.SetTitle("data_" + region_list[index])
    
    nobs_regionList = [ data.sumEntries() for data in regionDatasetList]

    tablenumbers['nobs'] = nobs_regionList


    # FROM HERE ON OUT WE CALCULATE THE FITTED NUMBER OF EVENTS __AFTER__ THE FIT
    
    #get a list of pdf's and variables per region
    pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in region_list]
    varinRegionList =  [ Util.GetRegionVar(w, region) for region in region_list]
  
    # if splitBins=True get the list of Nbins, binMax and binMin; make a list of new region names for each bin
    varNbinsInRegionList =  [] 
    varBinLowInRegionList = []  
    varBinHighInRegionList =  [] 
    rangeNameBinsInRegionList = [] 
  
    # if blinded=True, set all numbers of observed events to -1
    # if blinded: 
    #     for index, nobs in enumerate(nobs_regionListWithBins):
    #         nobs_regionListWithBins[index] = -1
    # tablenumbers['nobs'] = nobs_regionListWithBins


    #  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
    rrspdfinRegionList = []
    for index, pdf in enumerate(pdfinRegionList):
        if not pdf:
            print "WARNING: pdf is NULL for index {0}".format(index)
            continue
        prodList = pdf.pdfList()
        foundRRS = 0

        for idx in range(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt =  prodList[idx].createIntegral(ROOT.RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(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")
    
    # calculate total pdf number of fitted events and error
    nFittedInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
    pdfFittedErrInRegionList = [ Util.GetPropagatedError(pdf, resultAfterFit, True) for pdf in rrspdfinRegionList]

    tablenumbers['TOTAL_FITTED_bkg_events']        =  nFittedInRegionList
    tablenumbers['TOTAL_FITTED_bkg_events_err']    =  pdfFittedErrInRegionList
 
    # calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
    for isam, sample in enumerate(sample_list):

        sampleName = getName(sample)

        nSampleInRegionVal = []
        nSampleInRegionError = []
        sampleInAllRegions = ROOT.RooArgSet()
        
        for ireg, region in enumerate(region_list):
            sampleInRegion = getPdfInRegions(w, sample, region)
            sampleInRegionVal = 0.
            sampleInRegionError = 0.

            try: ##if sampleInRegion is not None:
                sampleInRegionVal = sampleInRegion.getVal()
                sampleInRegionError = Util.GetPropagatedError(sampleInRegion, resultAfterFit, True) 
                sampleInAllRegions.add(sampleInRegion)
            except:
                print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region =", region, "\n"
            nSampleInRegionVal.append(sampleInRegionVal)
            nSampleInRegionError.append(sampleInRegionError)
      
        tablenumbers['Fitted_events_'+sampleName]   = nSampleInRegionVal
        tablenumbers['Fitted_err_'+sampleName]   = nSampleInRegionError


  
    # FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS __BEFORRE__ THE FIT
    
    #load beforeFit workspace snapshot (=set all parameters to values before fit)
    w.loadSnapshot('snapshot_paramsVals_RooExpandedFitResult_beforeFit')

    # check if any of the initial scaling factors is != 1
    _result = w.obj('RooExpandedFitResult_beforeFit')
    _muFacs = _result.floatParsFinal()

    for i in xrange(len(_muFacs)):

        if "mu_" in _muFacs[i].GetName() and _muFacs[i].getVal() != 1.0:
            print  " \n WARNING: scaling factor %s != 1.0 (%g) expected MC yield WILL BE WRONG!" % (_muFacs[i].GetName(), _muFacs[i].getVal())
  
    # get a list of pdf's and variables per region
    pdfinRegionList = [ Util.GetRegionPdf(w, region)  for region in region_list]
    varinRegionList =  [ Util.GetRegionVar(w, region) for region in region_list]


    # get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
    rrspdfinRegionList = []
    for index,pdf in enumerate(pdfinRegionList):
        if not pdf: 
            print "WARNING: pdf is NULL for index {0}".format(index)
            continue
        prodList = pdf.pdfList()
        foundRRS = 0
        for idx in range(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt =  prodList[idx].createIntegral(ROOT.RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(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")

    # calculate total pdf number of expected events and error
    nExpInRegionList =  [ pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)]
    pdfExpErrInRegionList = [ Util.GetPropagatedError(pdf, resultBeforeFit, True)  for pdf in rrspdfinRegionList]
  
    tablenumbers['TOTAL_MC_EXP_BKG_events']    =  nExpInRegionList
    tablenumbers['TOTAL_MC_EXP_BKG_err']    =  pdfExpErrInRegionList
  
    # calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
    for isam, sample in enumerate(sample_list):
      
        sampleName = getName(sample)

        nMCSampleInRegionVal = []
        nMCSampleInRegionError = []
        MCSampleInAllRegions = ROOT.RooArgSet()

        for ireg, region in enumerate(region_list):
            MCSampleInRegion = getPdfInRegions(w,sample,region)
            MCSampleInRegionVal = 0.
            MCSampleInRegionError = 0.

            try:
                MCSampleInRegionVal = MCSampleInRegion.getVal()
                MCSampleInRegionError = Util.GetPropagatedError(MCSampleInRegion, resultBeforeFit, True) 
                MCSampleInAllRegions.add(MCSampleInRegion)
            except:
                print " \n WARNING: sample=", sampleName, " non-existent (empty) in region=",region
                
            nMCSampleInRegionVal.append(MCSampleInRegionVal)
            nMCSampleInRegionError.append(MCSampleInRegionError)

        tablenumbers['MC_exp_events_'+sampleName] = nMCSampleInRegionVal
        tablenumbers['MC_exp_err_'+sampleName] = nMCSampleInRegionError

    # sort the tablenumbers set
    map_listofkeys = tablenumbers.keys()
    map_listofkeys.sort()
  
    return tablenumbers
Пример #9
0
def latexfitresults(filename, region_list, sample_list):

    f = ROOT.TFile.Open(filename)
    w = f.Get('w')

    doAsym = True

    if w is None:
        print "ERROR : Cannot open workspace : w"
        sys.exit(1)

    resultAfterFit = w.obj('RooExpandedFitResult_afterFit')
    if resultAfterFit is None:
        print(
            "ERROR : Cannot open fit result after fit RooExpandedFitResult_afterFit"
        )
        sys.exit(1)

    resultBeforeFit = w.obj('RooExpandedFitResult_beforeFit')
    if resultBeforeFit is None:
        print(
            "ERROR : Cannot open fit result before fit RooExpandedFitResult_beforeFit"
        )
        sys.exit(1)

    # pick up dataset from workspace
    data_set = w.data('obsData')

    # pick up channel category (RooCategory) from workspace
    regionCat = w.obj("channelCat")

    # find full (long) name list of regions (i.e. short=SR3J, long=SR3J_meffInc30_JVF25pt50)
    regionFullNameList = [
        Util.GetFullRegionName(regionCat, region) for region in region_list
    ]

    # load afterFit workspace snapshot (=set all parameters to values after fit)
    snapshot = 'snapshot_paramsVals_RooExpandedFitResult_afterFit'
    w.loadSnapshot(snapshot)

    if not w.loadSnapshot(snapshot):
        print "ERROR : Cannot load snapshot : ", snapshot
        sys.exit(1)

    # define set, for all names/yields to be saved in
    tablenumbers = dict()

    tablenumbers['names'] = region_list

    # make a list of channelCat calls for every region
    regionCatList = [
        'channelCat==channelCat::' + region.Data()
        for region in regionFullNameList
    ]

    # retrieve number of observed (=data) events per region
    regionDatasetList = [
        data_set.reduce(regioncat) for regioncat in regionCatList
    ]
    for index, data in enumerate(regionDatasetList):
        data.SetName("data_" + region_list[index])
        data.SetTitle("data_" + region_list[index])

    nobs_regionList = [data.sumEntries() for data in regionDatasetList]

    tablenumbers['nobs'] = nobs_regionList

    # FROM HERE ON OUT WE CALCULATE THE FITTED NUMBER OF EVENTS __AFTER__ THE FIT

    #get a list of pdf's and variables per region
    pdfinRegionList = [Util.GetRegionPdf(w, region) for region in region_list]
    varinRegionList = [Util.GetRegionVar(w, region) for region in region_list]

    varNbinsInRegionList = []
    varBinLowInRegionList = []
    varBinHighInRegionList = []
    rangeNameBinsInRegionList = []

    #  get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
    rrspdfinRegionList = []
    for index, pdf in enumerate(pdfinRegionList):
        if not pdf:
            print "WARNING: pdf is NULL for index {0}".format(index)
            continue

        prodList = pdf.pdfList()
        foundRRS = 0

        for idx in range(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt = prodList[idx].createIntegral(
                    ROOT.RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(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")

    # calculate total pdf number of fitted events and error
    nFittedInRegionList = [
        pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)
    ]
    pdfFittedErrInRegionList = [
        Util.GetPropagatedError(pdf, resultAfterFit, doAsym)
        for pdf in rrspdfinRegionList
    ]

    tablenumbers['TOTAL_FITTED_bkg_events'] = nFittedInRegionList
    tablenumbers['TOTAL_FITTED_bkg_events_err'] = pdfFittedErrInRegionList

    # calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
    for isam, sample in enumerate(sample_list):

        sampleName = getName(sample)

        nSampleInRegionVal = []
        nSampleInRegionError = []
        sampleInAllRegions = ROOT.RooArgSet()

        for ireg, region in enumerate(region_list):
            sampleInRegion = getPdfInRegions(w, sample, region)
            sampleInRegionVal = 0.
            sampleInRegionError = 0.

            try:
                sampleInRegionVal = sampleInRegion.getVal()
                sampleInRegionError = Util.GetPropagatedError(
                    sampleInRegion, resultAfterFit, doAsym)
                sampleInAllRegions.add(sampleInRegion)
            except:
                print " \n YieldsTable.py: WARNING: sample =", sampleName, " non-existent (empty) in region =", region, "\n"

            nSampleInRegionVal.append(sampleInRegionVal)
            nSampleInRegionError.append(sampleInRegionError)

        tablenumbers['Fitted_events_' + sampleName] = nSampleInRegionVal
        tablenumbers['Fitted_err_' + sampleName] = nSampleInRegionError

    # FROM HERE ON OUT WE CALCULATE THE EXPECTED NUMBER OF EVENTS __BEFORRE__ THE FIT

    #load beforeFit workspace snapshot (=set all parameters to values before fit)
    w.loadSnapshot('snapshot_paramsVals_RooExpandedFitResult_beforeFit')

    # check if any of the initial scaling factors is != 1
    _result = w.obj('RooExpandedFitResult_beforeFit')
    _muFacs = _result.floatParsFinal()

    for i in xrange(len(_muFacs)):

        if "mu_" in _muFacs[i].GetName() and _muFacs[i].getVal() != 1.0:
            print " \n WARNING: scaling factor %s != 1.0 (%g) expected MC yield WILL BE WRONG!" % (
                _muFacs[i].GetName(), _muFacs[i].getVal())

    # get a list of pdf's and variables per region
    pdfinRegionList = [Util.GetRegionPdf(w, region) for region in region_list]
    varinRegionList = [Util.GetRegionVar(w, region) for region in region_list]

    # get a list of RooRealSumPdf per region (RooRealSumPdf is the top-pdf per region containing all samples)
    rrspdfinRegionList = []
    for index, pdf in enumerate(pdfinRegionList):
        if not pdf:
            print "WARNING: pdf is NULL for index {0}".format(index)
            continue
        prodList = pdf.pdfList()
        foundRRS = 0
        for idx in xrange(prodList.getSize()):
            if prodList[idx].InheritsFrom("RooRealSumPdf"):
                rrspdfInt = prodList[idx].createIntegral(
                    ROOT.RooArgSet(varinRegionList[index]))
                rrspdfinRegionList.append(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")

    # calculate total pdf number of expected events and error
    nExpInRegionList = [
        pdf.getVal() for index, pdf in enumerate(rrspdfinRegionList)
    ]
    pdfExpErrInRegionList = [
        Util.GetPropagatedError(pdf, resultBeforeFit, doAsym)
        for pdf in rrspdfinRegionList
    ]

    tablenumbers['TOTAL_MC_EXP_BKG_events'] = nExpInRegionList
    tablenumbers['TOTAL_MC_EXP_BKG_err'] = pdfExpErrInRegionList

    # calculate the fitted number of events and propagated error for each requested sample, by splitting off each sample pdf
    for isam, sample in enumerate(sample_list):

        sampleName = getName(sample)

        nMCSampleInRegionVal = []
        nMCSampleInRegionError = []
        MCSampleInAllRegions = ROOT.RooArgSet()

        for ireg, region in enumerate(region_list):
            MCSampleInRegion = getPdfInRegions(w, sample, region)
            MCSampleInRegionVal = 0.
            MCSampleInRegionError = 0.

            try:
                MCSampleInRegionVal = MCSampleInRegion.getVal()
                MCSampleInRegionError = Util.GetPropagatedError(
                    MCSampleInRegion, resultBeforeFit, doAsym)
                MCSampleInAllRegions.add(MCSampleInRegion)
            except:
                print " \n WARNING: sample=", sampleName, " non-existent (empty) in region=", region

            nMCSampleInRegionVal.append(MCSampleInRegionVal)
            nMCSampleInRegionError.append(MCSampleInRegionError)

        tablenumbers['MC_exp_events_' + sampleName] = nMCSampleInRegionVal
        tablenumbers['MC_exp_err_' + sampleName] = nMCSampleInRegionError

    # sort the tablenumbers set
    map_listofkeys = tablenumbers.keys()
    map_listofkeys.sort()

    f.Close()

    return tablenumbers