Ejemplo n.º 1
0
def cmodel(cid, nam, _f, _fOut, out_ws, diag, year, convention="BU"):

    # Some setup
    _fin = _f.Get("category_%s" % cid)
    _wspace = _fin.Get("wspace_%s" % cid)

    # ############################ USER DEFINED ###########################################################
    # First define the nominal transfer factors (histograms of signal/control, usually MC
    # note there are many tools available inside include/diagonalize.h for you to make
    # special datasets/histograms representing these and systematic effects
    # example below for creating shape systematic for photon which is just every bin up/down 30%

    metname = 'mjj'  # Observable variable name

    target = _fin.Get(
        "signal_ewkzjets"
    )  # define monimal (MC) of which process this config will model
    controlmc = _fin.Get(
        "Zmm_ewkzll")  # defines Zmm MC of which process will be controlled by
    controlmc_e = _fin.Get(
        "Zee_ewkzll")  # defines Zmm MC of which process will be controlled by
    controlmc_w = _fin.Get("signal_ewkwjets")
    controlmc_g = _fin.Get("gjets_ewkgjets")

    # Create the transfer factors and save them (not here you can also create systematic variations of these
    # transfer factors (named with extention _sysname_Up/Down
    ZmmScales = target.Clone()
    ZmmScales.SetName("ewk_zmm_weights_%s" % cid)
    ZmmScales.Divide(controlmc)
    _fOut.WriteTObject(ZmmScales)  # always write out to the directory

    ZeeScales = target.Clone()
    ZeeScales.SetName("ewk_zee_weights_%s" % cid)
    ZeeScales.Divide(controlmc_e)
    _fOut.WriteTObject(ZeeScales)  # always write out to the directory

    WZScales = target.Clone()
    WZScales.SetName("ewk_w_weights_%s" % cid)
    WZScales.Divide(controlmc_w)
    _fOut.WriteTObject(WZScales)  # always write out to the directory

    PhotonScales = target.Clone()
    PhotonScales.SetName("ewk_photon_weights_%s" % cid)
    PhotonScales.Divide(controlmc_g)
    _fOut.WriteTObject(PhotonScales)

    my_function(_wspace, _fin, _fOut, cid, diag, year)

    #######################################################################################################

    _bins = [
    ]  # take bins from some histogram, can choose anything but this is easy
    for b in range(target.GetNbinsX() + 1):
        _bins.append(target.GetBinLowEdge(b + 1))

    # Here is the important bit which "Builds" the control region, make a list of control regions which
    # are constraining this process, each "Channel" is created with ...
    #   (name,_wspace,out_ws,cid+'_'+model,TRANSFERFACTORS)
    # the second and third arguments can be left unchanged, the others instead must be set
    # TRANSFERFACTORS are what is created above, eg WScales

    CRs = [
        Channel("ewk_dimuon",
                _wspace,
                out_ws,
                cid + '_' + model,
                ZmmScales,
                convention=convention),
        Channel("ewk_dielectron",
                _wspace,
                out_ws,
                cid + '_' + model,
                ZeeScales,
                convention=convention),
        Channel("ewk_wjetssignal",
                _wspace,
                out_ws,
                cid + '_' + model,
                WZScales,
                convention=convention),
        Channel("ewk_photon",
                _wspace,
                out_ws,
                cid + '_' + model,
                PhotonScales,
                convention=convention)
    ]
    CRs[2].add_nuisance('CMS_veto{YEAR}_t'.format(YEAR=year), -0.01)
    CRs[2].add_nuisance('CMS_veto{YEAR}_m'.format(YEAR=year), -0.02)
    CRs[2].add_nuisance('CMS_veto{YEAR}_e'.format(YEAR=year), -0.03)

    # Get the JES/JER uncertainty file for transfer factors
    # Read the split uncertainties from there
    fjes = get_jes_jer_source_file_for_tf(category='vbf')
    jet_variations = get_jes_variations(fjes, year, proc='ewk')

    for var in jet_variations:
        add_variation(
            WZScales, fjes,
            'znunu_over_wlnu{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                             VARIATION=var),
            "ewk_w_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            WZScales, fjes, 'znunu_over_wlnu{YEAR}_ewk_{VARIATION}Down'.format(
                YEAR=year - 2000, VARIATION=var),
            "ewk_w_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[2].add_nuisance_shape(var, _fOut)

        add_variation(
            ZmmScales, fjes,
            'znunu_over_zmumu{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                              VARIATION=var),
            "ewk_zmm_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            ZmmScales, fjes,
            'znunu_over_zmumu{YEAR}_ewk_{VARIATION}Down'.format(YEAR=year -
                                                                2000,
                                                                VARIATION=var),
            "ewk_zmm_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[0].add_nuisance_shape(var, _fOut)

        add_variation(
            ZeeScales, fjes,
            'znunu_over_zee{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                            VARIATION=var),
            "ewk_zee_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            ZeeScales, fjes,
            'znunu_over_zee{YEAR}_ewk_{VARIATION}Down'.format(YEAR=year - 2000,
                                                              VARIATION=var),
            "ewk_zee_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[1].add_nuisance_shape(var, _fOut)

        add_variation(
            PhotonScales, fjes,
            'znunu_over_gjets{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                              VARIATION=var),
            "ewk_photon_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            PhotonScales, fjes,
            'znunu_over_gjets{YEAR}_ewk_{VARIATION}Down'.format(YEAR=year -
                                                                2000,
                                                                VARIATION=var),
            "ewk_photon_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[3].add_nuisance_shape(var, _fOut)

    # ############################ USER DEFINED ###########################################################
    # Add systematics in the following, for normalisations use name, relative size (0.01 --> 1%)
    # for shapes use add_nuisance_shape with (name,_fOut)
    # note, the code will LOOK for something called NOMINAL_name_Up and NOMINAL_name_Down, where NOMINAL=WScales.GetName()
    # these must be created and writted to the same dirctory as the nominal (fDir)

    # Bin by bin nuisances to cover statistical uncertainties ...

    do_stat_unc(ZmmScales,
                proc='ewk_zmm',
                region='ewk_dimuonCR',
                CR=CRs[0],
                cid=cid,
                outfile=_fOut)
    do_stat_unc(ZeeScales,
                proc='ewk_zee',
                region='ewk_dielectronCR',
                CR=CRs[1],
                cid=cid,
                outfile=_fOut)
    do_stat_unc(WZScales,
                proc='ewk_w',
                region='ewk_wzCR',
                CR=CRs[2],
                cid=cid,
                outfile=_fOut)
    do_stat_unc(PhotonScales,
                proc='ewk_photon',
                region='ewk_photonCR',
                CR=CRs[3],
                cid=cid,
                outfile=_fOut)

    #######################################################################################################

    CRs[2].add_nuisance_shape("ZnunuWJets_EWK_renscale_vbf", _fOut)
    CRs[2].add_nuisance_shape("ZnunuWJets_EWK_facscale_vbf", _fOut)
    CRs[2].add_nuisance_shape("ZnunuWJets_EWK_pdf_vbf", _fOut)

    for b in range(target.GetNbinsX()):
        CRs[2].add_nuisance_shape(
            "ewk_ewk_%s_bin%d" % (re.sub("_201(\d)", "", cid), b), _fOut)

    CRs[3].add_nuisance_shape("Photon_EWK_renscale_vbf", _fOut)
    CRs[3].add_nuisance_shape("Photon_EWK_facscale_vbf", _fOut)
    CRs[3].add_nuisance_shape("Photon_EWK_pdf_vbf", _fOut)

    for b in range(target.GetNbinsX()):
        CRs[3].add_nuisance_shape(
            "ewkphoton_ewk_%s_bin%d" % (re.sub("_201(\d)", "", cid), b), _fOut)

    #######################################################################################################

    cat = Category(model,
                   cid,
                   nam,
                   _fin,
                   _fOut,
                   _wspace,
                   out_ws,
                   _bins,
                   metname,
                   target.GetName(),
                   CRs,
                   diag,
                   convention=convention)
    cat.setDependant("qcd_zjets", "ewkqcd_signal")
    # Return of course
    return cat
Ejemplo n.º 2
0
def cmodel(cid, nam, _f, _fOut, out_ws, diag, year):

    # Some setup
    _fin = _f.Get("category_%s" % cid)
    _wspace = _fin.Get("wspace_%s" % cid)

    # ############################ USER DEFINED ###########################################################
    # First define the nominal transfer factors (histograms of signal/control, usually MC
    # note there are many tools available inside include/diagonalize.h for you to make
    # special datasets/histograms representing these and systematic effects
    # example below for creating shape systematic for photon which is just every bin up/down 30%

    metname = "met"  # Observable variable name
    gvptname = "genBosonPt"  # Weights are in generator pT

    target = _fin.Get(
        "signal_zjets"
    )  # define monimal (MC) of which process this config will model
    controlmc = _fin.Get(
        "Zmm_zll")  # defines Zmm MC of which process will be controlled by
    controlmc_photon = _fin.Get(
        "gjets_gjets"
    )  # defines Gjets MC of which process will be controlled by
    controlmc_e = _fin.Get(
        "Zee_zll")  # defines Zmm MC of which process will be controlled by
    controlmc_w = _fin.Get("signal_wjets")

    # Create the transfer factors and save them (not here you can also create systematic variations of these
    # transfer factors (named with extention _sysname_Up/Down
    ZmmScales = target.Clone()
    ZmmScales.SetName("zmm_weights_%s" % cid)
    ZmmScales.Divide(controlmc)
    _fOut.WriteTObject(ZmmScales)  # always write out to the directory

    ZeeScales = target.Clone()
    ZeeScales.SetName("zee_weights_%s" % cid)
    ZeeScales.Divide(controlmc_e)
    _fOut.WriteTObject(ZeeScales)  # always write out to the directory

    WZScales = target.Clone()
    WZScales.SetName("w_weights_%s" % cid)
    WZScales.Divide(controlmc_w)
    _fOut.WriteTObject(WZScales)  # always write out to the directory

    my_function(_wspace, _fin, _fOut, cid, diag)
    PhotonScales = _fOut.Get("photon_weights_%s" % cid)

    #######################################################################################################

    _bins = [
    ]  # take bins from some histogram, can choose anything but this is easy
    for b in range(target.GetNbinsX() + 1):
        _bins.append(target.GetBinLowEdge(b + 1))

    # Here is the important bit which "Builds" the control region, make a list of control regions which
    # are constraining this process, each "Channel" is created with ...
    # 	(name,_wspace,out_ws,cid+'_'+model,TRANSFERFACTORS)
    # the second and third arguments can be left unchanged, the others instead must be set
    # TRANSFERFACTORS are what is created above, eg WScales

    CRs = [
        Channel("photon", _wspace, out_ws, cid + '_' + model, PhotonScales),
        Channel("dimuon", _wspace, out_ws, cid + '_' + model, ZmmScales),
        Channel("dielectron", _wspace, out_ws, cid + '_' + model, ZeeScales),
        Channel("wjetssignal", _wspace, out_ws, cid + '_' + model, WZScales)
    ]

    # ############################ USER DEFINED ###########################################################
    # Add systematics in the following, for normalisations use name, relative size (0.01 --> 1%)
    # for shapes use add_nuisance_shape with (name,_fOut)
    # note, the code will LOOK for something called NOMINAL_name_Up and NOMINAL_name_Down, where NOMINAL=WScales.GetName()
    # these must be created and writted to the same dirctory as the nominal (fDir)

    if "monov" in cid:
        tag = "_monov"
    else:
        tag = ""

    do_stat_unc(PhotonScales, "photon", cid, "photonCR", CRs[0], _fOut)
    do_stat_unc(ZmmScales, "zmm", cid, "dimuonCR", CRs[1], _fOut)
    do_stat_unc(ZeeScales, "zee", cid, "dielectronCR", CRs[2], _fOut)
    do_stat_unc(WZScales, "w", cid, "wzCR", CRs[3], _fOut)

    ## Here now adding the trigger uncertainty
    fztoz_trig = r.TFile.Open("sys/all_trig_2017.root")  # 250 - 1400 binning

    # We want to correlate experimental uncertainties between the loose and tight regions.
    cid_corr = re.sub("(loose|tight)", "", cid)

    add_variation(PhotonScales, fztoz_trig, "trig_sys_down" + tag,
                  "photon_weights_%s_mettrig_%s_Down" % (cid, year), _fOut)
    add_variation(PhotonScales, fztoz_trig, "trig_sys_up" + tag,
                  "photon_weights_%s_mettrig_%s_Up" % (cid, year), _fOut)
    CRs[0].add_nuisance_shape("mettrig_%s" % year, _fOut)

    # Take the square of the uncertainty because we are going from zero to two leptons
    add_variation(ZmmScales, fztoz_trig, "trig_sys_sqr_down" + tag,
                  "zmm_weights_%s_mettrig_%s_Down" % (cid, year), _fOut)
    add_variation(ZmmScales, fztoz_trig, "trig_sys_sqr_up" + tag,
                  "zmm_weights_%s_mettrig_%s_Up" % (cid, year), _fOut)
    CRs[1].add_nuisance_shape("mettrig_%s" % year, _fOut)

    ## Here now adding the trigger uncertainty
    add_variation(ZeeScales, fztoz_trig, "trig_sys_down" + tag,
                  "zee_weights_%s_mettrig_%s_Down" % (cid, year), _fOut)
    add_variation(ZeeScales, fztoz_trig, "trig_sys_up" + tag,
                  "zee_weights_%s_mettrig_%s_Up" % (cid, year), _fOut)
    CRs[2].add_nuisance_shape("mettrig_%s" % year, _fOut)

    #######################################################################################################

    CRs[0].add_nuisance_shape("qcd", _fOut)
    CRs[0].add_nuisance_shape("qcdshape", _fOut)
    CRs[0].add_nuisance_shape("qcdprocess", _fOut)
    CRs[0].add_nuisance_shape("ewk", _fOut)
    CRs[0].add_nuisance_shape("sudakovZ", _fOut)
    CRs[0].add_nuisance_shape("sudakovG", _fOut)
    CRs[0].add_nuisance_shape("nnlomissZ", _fOut)
    CRs[0].add_nuisance_shape("nnlomissG", _fOut)
    CRs[0].add_nuisance_shape("cross", _fOut)
    CRs[0].add_nuisance_shape("pdf", _fOut)

    CRs[3].add_nuisance_shape("wqcd", _fOut)
    CRs[3].add_nuisance_shape("wqcdshape", _fOut)
    CRs[3].add_nuisance_shape("wqcdprocess", _fOut)
    CRs[3].add_nuisance_shape("wewk", _fOut)
    CRs[3].add_nuisance_shape("sudakovZ", _fOut)
    CRs[3].add_nuisance_shape("sudakovW", _fOut)
    CRs[3].add_nuisance_shape("nnlomissZ", _fOut)
    CRs[3].add_nuisance_shape("nnlomissW", _fOut)
    CRs[3].add_nuisance_shape("wcross", _fOut)
    CRs[3].add_nuisance_shape("wpdf", _fOut)

    #######################################################################################################

    cat = Category(model, cid, nam, _fin, _fOut, _wspace, out_ws, _bins,
                   metname, target.GetName(), CRs, diag)
    # Return of course
    return cat
Ejemplo n.º 3
0
def cmodel(cid, nam, _f, _fOut, out_ws, diag, year, convention="BU"):

    # Some setup
    _fin = _f.Get("category_%s" % cid)
    _wspace = _fin.Get("wspace_%s" % cid)

    # ############################ USER DEFINED ###########################################################
    # First define the nominal transfer factors (histograms of signal/control, usually MC
    # note there are many tools available inside include/diagonalize.h for you to make
    # special datasets/histograms representing these and systematic effects
    # but for now this is just kept simple
    processName = "WJets"  # Give a name of the process being modelled
    metname = 'mjj'  # Observable variable name
    targetmc = _fin.Get(
        "signal_ewkwjets"
    )  # define monimal (MC) of which process this config will model
    controlmc = _fin.Get("Wmn_ewkwjets")  # defines in / out acceptance
    controlmc_e = _fin.Get("Wen_ewkwjets")  # defines in / out acceptance

    # Create the transfer factors and save them (not here you can also create systematic variations of these
    # transfer factors (named with extention _sysname_Up/Down

    WScales = targetmc.Clone()
    WScales.SetName("ewk_wmn_weights_%s" % cid)
    WScales.Divide(controlmc)
    _fOut.WriteTObject(WScales)

    WScales_e = targetmc.Clone()
    WScales_e.SetName("ewk_wen_weights_%s" % cid)
    WScales_e.Divide(controlmc_e)
    _fOut.WriteTObject(WScales_e)

    #######################################################################################################

    _bins = [
    ]  # take bins from some histogram, can choose anything but this is easy
    for b in range(targetmc.GetNbinsX() + 1):
        _bins.append(targetmc.GetBinLowEdge(b + 1))

    # Here is the important bit which "Builds" the control region, make a list of control regions which
    # are constraining this process, each "Channel" is created with ...
    #   (name,_wspace,out_ws,cid+'_'+model,TRANSFERFACTORS)
    # the second and third arguments can be left unchanged, the others instead must be set
    # TRANSFERFACTORS are what is created above, eg WScales

    CRs = [
        Channel("ewk_singlemuon",
                _wspace,
                out_ws,
                cid + '_' + model,
                WScales,
                convention=convention),
        Channel("ewk_singleelectron",
                _wspace,
                out_ws,
                cid + '_' + model,
                WScales_e,
                convention=convention),
    ]

    # Get the JES/JER unlcertainty file for transfer factors
    # Read the split uncertainties from there
    fjes = get_jes_jer_source_file_for_tf(category='vbf')
    jet_variations = get_jes_variations(fjes, year, proc='ewk')

    for var in jet_variations:
        add_variation(
            WScales, fjes,
            'wlnu_over_wmunu{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                             VARIATION=var),
            "ewk_wmn_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            WScales, fjes, 'wlnu_over_wmunu{YEAR}_ewk_{VARIATION}Down'.format(
                YEAR=year - 2000, VARIATION=var),
            "ewk_wmn_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[0].add_nuisance_shape(var, _fOut)

        add_variation(
            WScales_e, fjes,
            'wlnu_over_wenu{YEAR}_ewk_{VARIATION}Up'.format(YEAR=year - 2000,
                                                            VARIATION=var),
            "ewk_wen_weights_%s_%s_Up" % (cid, var), _fOut)
        add_variation(
            WScales_e, fjes,
            'wlnu_over_wenu{YEAR}_ewk_{VARIATION}Down'.format(YEAR=year - 2000,
                                                              VARIATION=var),
            "ewk_wen_weights_%s_%s_Down" % (cid, var), _fOut)
        CRs[1].add_nuisance_shape(var, _fOut)

    for c in CRs:
        c.add_nuisance('CMS_veto{YEAR}_t'.format(YEAR=year), 0.01)
        c.add_nuisance('CMS_veto{YEAR}_m'.format(YEAR=year), 0.02)
        c.add_nuisance('CMS_veto{YEAR}_e'.format(YEAR=year), 0.03)

    # ############################ USER DEFINED ###########################################################
    # Add systematics in the following, for normalisations use name, relative size (0.01 --> 1%)
    # for shapes use add_nuisance_shape with (name,_fOut)
    # note, the code will LOOK for something called NOMINAL_name_Up and NOMINAL_name_Down, where NOMINAL=WScales.GetName()
    # these must be created and writted to the same dirctory as the nominal (fDir)
    do_stat_unc(WScales,
                proc='ewk_wmn',
                region='ewk_singlemuon',
                CR=CRs[0],
                cid=cid,
                outfile=_fOut)
    do_stat_unc(WScales_e,
                proc='ewk_wen',
                region='ewk_singleelectron',
                CR=CRs[1],
                cid=cid,
                outfile=_fOut)

    #######################################################################################################

    cat = Category(model,
                   cid,
                   nam,
                   _fin,
                   _fOut,
                   _wspace,
                   out_ws,
                   _bins,
                   metname,
                   targetmc.GetName(),
                   CRs,
                   diag,
                   convention=convention)
    cat.setDependant(
        "ewk_zjets", "ewk_wjetssignal"
    )  # Can use this to state that the "BASE" of this is already dependant on another process
    # EG if the W->lv in signal is dependant on the Z->vv and then the W->mv is depenant on W->lv, then
    # give the arguments model,channel name from the config which defines the Z->vv => W->lv map!
    # Return of course
    return cat
Ejemplo n.º 4
0
def cmodel(cid,nam,_f,_fOut, out_ws, diag, year):
  filler = {
    "YEAR" : year,
    "CID" : cid,
    "CHANNEL" : "monojet" if "monojet" in cid else "monov"
  }
  # Some setup
  _fin = _f.Get("category_%s"%cid)
  _wspace = _fin.Get("wspace_%s"%cid)

  # ############################ USER DEFINED ###########################################################
  # First define the nominal transfer factors (histograms of signal/control, usually MC
  # note there are many tools available inside include/diagonalize.h for you to make
  # special datasets/histograms representing these and systematic effects
  # example below for creating shape systematic for photon which is just every bin up/down 30%

  metname    = "met"          # Observable variable name
  gvptname   = "genBosonPt"   # Weights are in generator pT

  target             = _fin.Get("signal_zjets")      # define monimal (MC) of which process this config will model
  controlmc          = _fin.Get("Zmm_zll")           # defines Zmm MC of which process will be controlled by
  controlmc_photon   = _fin.Get("gjets_gjets")       # defines Gjets MC of which process will be controlled by
  controlmc_e        = _fin.Get("Zee_zll")           # defines Zmm MC of which process will be controlled by
  controlmc_w        = _fin.Get("signal_wjets")

  # Save the original spectra
  WSpectrum      = controlmc_w.Clone("w_spectrum_%s_"%cid)
  PhotonSpectrum = controlmc_photon.Clone("photon_spectrum_%s_"%cid)
  ZvvSpectrum 	 = target.Clone("zvv_spectrum_%s_"%cid)
  _fOut.WriteTObject( WSpectrum )
  _fOut.WriteTObject( PhotonSpectrum )
  _fOut.WriteTObject( ZvvSpectrum )

  # Create the transfer factors and save them (not here you can also create systematic variations of these
  # transfer factors (named with extention _sysname_Up/Down
  ZmmScales = target.Clone("zmm_weights_%s"%cid)
  ZmmScales.Divide(controlmc)
  _fOut.WriteTObject(ZmmScales)

  ZeeScales = target.Clone("zee_weights_%s"%cid);
  ZeeScales.Divide(controlmc_e)
  _fOut.WriteTObject(ZeeScales)

  WZScales = target.Clone("w_weights_%s"%cid);
  WZScales.Divide(controlmc_w)
  _fOut.WriteTObject(WZScales)

  PhotonScales = target.Clone("photon_weights_%s"%cid);
  PhotonScales.Divide(controlmc_photon)
  _fOut.WriteTObject(PhotonScales)

  #######################################################################################################

  _bins = []  # take bins from some histogram, can choose anything but this is easy
  for b in range(target.GetNbinsX()+1):
    _bins.append(target.GetBinLowEdge(b+1))

  # Here is the important bit which "Builds" the control region, make a list of control regions which
  # are constraining this process, each "Channel" is created with ...
  # 	(name,_wspace,out_ws,cid+'_'+model,TRANSFERFACTORS)
  # the second and third arguments can be left unchanged, the others instead must be set
  # TRANSFERFACTORS are what is created above, eg WScales

  CRs = [
   Channel("photon",_wspace,out_ws,cid+'_'+model,PhotonScales)
  ,Channel("dimuon",_wspace,out_ws,cid+'_'+model,ZmmScales)
  ,Channel("dielectron",_wspace,out_ws,cid+'_'+model,ZeeScales)
  ,Channel("wjetssignal",_wspace,out_ws,cid+'_'+model,WZScales)
  ]
  # my_function(_wspace,_fin,_fOut,cid,diag, filler)

  # ############################ USER DEFINED ###########################################################
  # Add systematics in the following, for normalisations use name, relative size (0.01 --> 1%)
  # for shapes use add_nuisance_shape with (name,_fOut)
  # note, the code will LOOK for something called NOMINAL_name_Up and NOMINAL_name_Down, where NOMINAL=WScales.GetName()
  # these must be created and writted to the same dirctory as the nominal (fDir)

  if "monov" in cid:
    tag = "_monov"
  else:
    tag = ""

  do_stat_unc(PhotonScales, "photon", cid, "photonCR", CRs[0],_fOut)
  do_stat_unc(ZmmScales, "zmm", cid, "dimuonCR", CRs[1],_fOut)
  do_stat_unc(ZeeScales, "zee", cid, "dielectronCR", CRs[2],_fOut)
  do_stat_unc(WZScales, "w", cid, "wzCR", CRs[3],_fOut)

  ## Here now adding the trigger uncertainty
  fztoz_trig = r.TFile.Open("sys/all_trig_2017.root") # 250 - 1400 binning

  # We want to correlate experimental uncertainties between the loose and tight regions.
  cid_corr = re.sub("(loose|tight)","",cid)

  # Take the square of the uncertainty because we are going from zero to two leptons
  add_variation(ZmmScales,fztoz_trig,"trig_sys_sqr_down"+tag,"zmm_weights_%s_mettrig_%s_Down"%(cid,year), _fOut)
  add_variation(ZmmScales,fztoz_trig,"trig_sys_sqr_up"+tag,"zmm_weights_%s_mettrig_%s_Up"%(cid,year), _fOut)
  CRs[1].add_nuisance_shape("mettrig_%s"%year,_fOut, functype='quadratic')

  #######################################################################################################

  ftheo = ROOT.TFile("sys/vjets_reco_theory_unc.root")

  # Theory uncertainties on Z/Gamma
  for variation, name in [
                           ('d1k', 'qcd'),
                           ('d2k', 'qcdshape'),
                           ('d3k', 'qcdprocess'),
                           ('d1kappa', 'ewk'),
                           ('d2kappa_g', 'nnlomissG'),
                           ('d2kappa_z', 'nnlomissZ'),
                           ('d3kappa_g', 'sudakovG'),
                           ('d3kappa_z', 'sudakovZ'),
                           ('mix', 'cross')
                           ]:
    # Flip nuisance directions for compatibility with 2016
    invert = variation in ['d2kappa','d3kappa']
    for direction in 'up', 'down':
      add_variation(
                    PhotonScales,
                    ftheo,
                    "{CHANNEL}_z_over_g_{VARIATION}_{DIR}".format(VARIATION=variation,DIR=direction,**filler),
                    "photon_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
                    _fOut,
                    invert=invert
                    )

    CRs[0].add_nuisance_shape(name, _fOut, functype='quadratic')

  # Theory uncertainties on Z/W
  for variation, name in [
                           ('d1k', 'wqcd'),
                           ('d2k', 'wqcdshape'),
                           ('d3k', 'wqcdprocess'),
                           ('d1kappa', 'wewk'),
                           ('d2kappa_w', 'nnlomissW'),
                           ('d2kappa_z', 'nnlomissZ'),
                           ('d3kappa_w', 'sudakovW'),
                           ('d3kappa_z', 'sudakovZ'),
                           ('mix', 'wcross')
                           ]:
    # Flip nuisance directions for compatibility with 2016
    invert = variation in ['d1k','d3k','d1kappa','d2kappa_w','d3kappa_w']
    for direction in 'up', 'down':
      add_variation(
                  WZScales,
                  ftheo,
                  "{CHANNEL}_z_over_w_{VARIATION}_{DIR}".format(VARIATION=variation,DIR=direction,**filler),
                  "w_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
                  _fOut,
                  invert=invert
                  )
    CRs[3].add_nuisance_shape(name, _fOut, functype='quadratic')


  # Mistag nuisances
  fmistag = ROOT.TFile("sys/mistag_sf_variations.root")
  region_wp = determine_region_wp(cid)
  for sf_wp in 'loose','tight':
    scale, flip = mistag_scale_and_flip(sf_wp, region_wp)
    if scale == 0:
      continue
    # Gamma uncertainty on Z/gamma ratio
    for variation_index in range(2):
      name = 'CMS_eff{YEAR}_vmistag_g_stat_{SF_WP}_{INDEX}'.format(INDEX=variation_index,  SF_WP=sf_wp, **filler)
      for direction in 'up','down':
        add_variation(
          PhotonScales,
          fmistag,
          'g_{SF_WP}_{YEAR}_{CHANNEL}_var{INDEX}_{DIR}'.format(INDEX=variation_index,DIR=direction, SF_WP=sf_wp, **filler),
          "photon_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
          _fOut,
          invert = not flip,
          scale=scale
        )
      CRs[0].add_nuisance_shape(name, _fOut, functype='quadratic')

    # Z uncertainty on Z/gamma ratio
    for variation_index in range(2):
      name = 'CMS_eff{YEAR}_vmistag_z_stat_{SF_WP}_{INDEX}'.format(INDEX=variation_index,  SF_WP=sf_wp, **filler)
      for direction in 'up','down':
        add_variation(
          PhotonScales,
          fmistag,
          'z_{SF_WP}_{YEAR}_{CHANNEL}_var{INDEX}_{DIR}'.format(INDEX=variation_index,DIR=direction,  SF_WP=sf_wp, **filler),
          "photon_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
          _fOut,
          invert=flip,
          scale=scale
        )
      CRs[0].add_nuisance_shape(name, _fOut, functype='quadratic')

    # Z uncertainty on Z/W ratio
    for variation_index in range(2):
      name = 'CMS_eff{YEAR}_vmistag_z_stat_{SF_WP}_{INDEX}'.format(INDEX=variation_index,  SF_WP=sf_wp, **filler)
      for direction in 'up','down':
        add_variation(
          WZScales,
          fmistag,
          'z_{SF_WP}_{YEAR}_{CHANNEL}_var{INDEX}_{DIR}'.format(INDEX=variation_index, DIR=direction,  SF_WP=sf_wp, **filler),
          "w_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
          _fOut,
          invert=flip,
          scale=scale
        )
      CRs[3].add_nuisance_shape(name, _fOut, functype='quadratic')

    # W uncertainty on Z/W ratio
    for variation_index in range(2):
      name = 'CMS_eff{YEAR}_vmistag_w_stat_{SF_WP}_{INDEX}'.format(INDEX=variation_index,  SF_WP=sf_wp, **filler)
      for direction in 'up','down':
        add_variation(
          WZScales,
          fmistag,
          'w_{SF_WP}_{YEAR}_{CHANNEL}_var{INDEX}_{DIR}'.format(INDEX=variation_index,  SF_WP=sf_wp, DIR=direction, **filler),
          "w_weights_{CID}_{NAME}_{DIR}".format(NAME=name,DIR=direction.capitalize(),**filler),
          _fOut,
          invert=not flip,
          scale=scale
        )
      CRs[3].add_nuisance_shape(name, _fOut, functype='quadratic')





  # PDF uncertainties
  fpdf = ROOT.TFile("sys/tf_pdf_unc.root")

  for direction in 'up', 'down':
    add_variation(
      PhotonScales,
      fpdf,
      "{CHANNEL}_z_over_g_pdf_{YEAR}_{DIR}".format(DIR=direction,**filler),
      "photon_weights_{CID}_z_over_g_pdf_{DIR}".format(DIR=direction.capitalize(), **filler),
      _fOut
    )
    add_variation(
      ZmmScales,
      fpdf,
      "{CHANNEL}_z_over_zmm_pdf_{YEAR}_{DIR}".format(DIR=direction,**filler),
      "zmm_weights_{CID}_z_over_z_pdf_{DIR}".format(DIR=direction.capitalize(), **filler),
      _fOut
    )
    add_variation(
      ZeeScales,
      fpdf,
      "{CHANNEL}_z_over_zee_pdf_{YEAR}_{DIR}".format(DIR=direction,**filler),
      "zee_weights_{CID}_z_over_z_pdf_{DIR}".format(DIR=direction.capitalize(), **filler),
      _fOut
    )
    add_variation(
      WZScales,
      fpdf,
      "{CHANNEL}_z_over_w_pdf_{YEAR}_{DIR}".format(DIR=direction,**filler),
      "w_weights_{CID}_z_over_w_pdf_{DIR}".format(DIR=direction.capitalize(), **filler),
      _fOut
    )

  CRs[0].add_nuisance_shape("z_over_g_pdf",_fOut, functype='quadratic')
  CRs[1].add_nuisance_shape("z_over_z_pdf",_fOut, functype='quadratic')
  CRs[2].add_nuisance_shape("z_over_z_pdf",_fOut, functype='quadratic')
  CRs[3].add_nuisance_shape("z_over_w_pdf",_fOut, functype='quadratic')



  #######################################################################################################


  # Veto uncertainties
  ftauveto = r.TFile.Open("sys/tau_veto_unc.root")
  fmuveto = r.TFile.Open("sys/muon_veto_unc.root")
  felveto = r.TFile.Open("sys/ele_veto_unc.root")

  # The transfer factor here is Z(SR) / W(SR)
  # -> Invert the veto shapes relative to W_constraints, where the TF is W(SR) / W(CR)
  add_variation(WZScales, felveto, "ele_id_veto_sys_{CHANNEL}_up_{YEAR}".format(**filler), "w_weights_%s_eveto_id_%s_Up"%(cid, year), _fOut,invert=True)
  add_variation(WZScales, felveto, "ele_id_veto_sys_{CHANNEL}_down_{YEAR}".format(**filler), "w_weights_%s_eveto_id_%s_Down"%(cid, year), _fOut,invert=True)
  CRs[3].add_nuisance_shape("eveto_id_%s"%year,_fOut, functype='quadratic')

  add_variation(WZScales, felveto, "ele_reco_veto_sys_{CHANNEL}_up_{YEAR}".format(**filler), "w_weights_%s_eveto_reco_%s_Up"%(cid, year), _fOut,invert=True)
  add_variation(WZScales, felveto, "ele_reco_veto_sys_{CHANNEL}_down_{YEAR}".format(**filler), "w_weights_%s_eveto_reco_%s_Down"%(cid, year), _fOut,invert=True)
  CRs[3].add_nuisance_shape("eveto_reco_%s"%year,_fOut, functype='quadratic')

  add_variation(WZScales, ftauveto, "tau_id_veto_sys_{CHANNEL}_up_{YEAR}".format(**filler), "w_weights_%s_tauveto_%s_Up"%(cid, year), _fOut,invert=True)
  add_variation(WZScales, ftauveto, "tau_id_veto_sys_{CHANNEL}_down_{YEAR}".format(**filler), "w_weights_%s_tauveto_%s_Down"%(cid, year), _fOut,invert=True)
  CRs[3].add_nuisance_shape("tauveto_%s"%year,_fOut, functype='quadratic')

  add_variation(WZScales, fmuveto, "muon_id_veto_sys_{CHANNEL}_up_{YEAR}".format(**filler), "w_weights_%s_muveto_id_%s_Up"%(cid, year), _fOut,invert=True)
  add_variation(WZScales, fmuveto, "muon_id_veto_sys_{CHANNEL}_down_{YEAR}".format(**filler), "w_weights_%s_muveto_id_%s_Down"%(cid, year), _fOut,invert=True)
  CRs[3].add_nuisance_shape("muveto_id_%s"%year,_fOut, functype='quadratic')

  add_variation(WZScales, fmuveto, "muon_iso_veto_sys_{CHANNEL}_up_{YEAR}".format(**filler), "w_weights_%s_muveto_iso_%s_Up"%(cid, year), _fOut,invert=True)
  add_variation(WZScales, fmuveto, "muon_iso_veto_sys_{CHANNEL}_down_{YEAR}".format(**filler), "w_weights_%s_muveto_iso_%s_Down"%(cid, year), _fOut,invert=True)
  CRs[3].add_nuisance_shape("muveto_iso_%s"%year,_fOut, functype='quadratic')

  # Prefiring uncertainty
  # The shape in the input file is just one histogram to be used for up/down
  # -> need to invert for one variation
  # Note that the "invert" argument is the other way round for electrons and muons
  # To take into account the anticorrelation between them
  if year == 2017:
    fpref = r.TFile.Open("sys/pref_unc.root")

    add_variation(ZmmScales, fpref, "{CHANNEL}_pref_unc_z_over_mm".format(**filler), "zmm_weights_%s_prefiring_Up"%cid, _fOut)
    add_variation(ZmmScales, fpref, "{CHANNEL}_pref_unc_z_over_mm".format(**filler), "zmm_weights_%s_prefiring_Down"%cid, _fOut,invert=True)
    CRs[1].add_nuisance_shape("prefiring",_fOut, functype='quadratic')

    add_variation(ZeeScales, fpref, "{CHANNEL}_pref_unc_z_over_ee".format(**filler), "zee_weights_%s_prefiring_Up"%cid, _fOut,invert=True)
    add_variation(ZeeScales, fpref, "{CHANNEL}_pref_unc_z_over_ee".format(**filler), "zee_weights_%s_prefiring_Down"%cid, _fOut)
    CRs[2].add_nuisance_shape("prefiring",_fOut, functype='quadratic')


  fphotonid = r.TFile.Open("sys/photon_id_unc.root")
  add_variation(PhotonScales, fphotonid, "{CHANNEL}_{YEAR}_photon_id_up".format(**filler), "photon_weights_%s_CMS_eff%s_pho_Up"%(cid, year), _fOut, invert=True, scale=2.0)
  add_variation(PhotonScales, fphotonid, "{CHANNEL}_{YEAR}_photon_id_dn".format(**filler), "photon_weights_%s_CMS_eff%s_pho_Down"%(cid, year), _fOut, invert=True, scale=2.0)
  CRs[0].add_nuisance_shape("CMS_eff{YEAR}_pho".format(**filler),_fOut, functype='quadratic')
  add_variation(PhotonScales, fphotonid, "{CHANNEL}_{YEAR}_photon_id_extrap_up".format(**filler), "photon_weights_%s_CMS_eff%s_pho_extrap_Up"%(cid, year), _fOut, invert=True, scale=2.0)
  add_variation(PhotonScales, fphotonid, "{CHANNEL}_{YEAR}_photon_id_extrap_dn".format(**filler), "photon_weights_%s_CMS_eff%s_pho_extrap_Down"%(cid, year), _fOut, invert=True, scale=2.0)
  CRs[0].add_nuisance_shape("CMS_eff{YEAR}_pho_extrap".format(**filler),_fOut, functype='quadratic')

  felectronid = r.TFile.Open("sys/ele_id_unc.root")
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_id_stat_up".format(**filler), "zee_weights_%s_CMS_eff%s_e_stat_Up"%(cid, year), _fOut, invert=True, scale=2.0)
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_id_stat_dn".format(**filler), "zee_weights_%s_CMS_eff%s_e_stat_Down"%(cid, year), _fOut, invert=True, scale=2.0)
  CRs[2].add_nuisance_shape("CMS_eff{YEAR}_e_stat".format(**filler),_fOut, functype='quadratic')
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_id_syst_up".format(**filler), "zee_weights_%s_CMS_eff%s_e_syst_Up"%(cid, year), _fOut, invert=True, scale=2.0)
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_id_syst_dn".format(**filler), "zee_weights_%s_CMS_eff%s_e_syst_Down"%(cid, year), _fOut, invert=True, scale=2.0)
  CRs[2].add_nuisance_shape("CMS_eff{YEAR}_e_syst".format(**filler),_fOut, functype='quadratic')
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_reco_up".format(**filler), "zee_weights_%s_CMS_eff%s_e_reco_Up"%(cid, year), _fOut, invert=True)
  add_variation(ZeeScales, felectronid, "{CHANNEL}_{YEAR}_2e_reco_dn".format(**filler), "zee_weights_%s_CMS_eff%s_e_reco_Down"%(cid, year), _fOut, invert=True)
  CRs[2].add_nuisance_shape("CMS_eff{YEAR}_e_reco".format(**filler),_fOut, functype='quadratic')

  # JES uncertainties
  fjes = get_jes_jer_source_file_for_tf(category='monojet')
  jet_variations = get_jes_variations(fjes, year)

  print "VARIATIONS"
  print jet_variations
  for var in jet_variations:
    add_variation(WZScales, fjes, 'znunu_over_wlnu{YEAR}_qcd_{VARIATION}Up'.format(YEAR=year-2000, VARIATION=var), "w_weights_%s_%s_Up"%(cid, var), _fOut)
    add_variation(WZScales, fjes, 'znunu_over_wlnu{YEAR}_qcd_{VARIATION}Down'.format(YEAR=year-2000, VARIATION=var), "w_weights_%s_%s_Down"%(cid, var), _fOut)
    CRs[3].add_nuisance_shape(var,_fOut, functype='quadratic')

    add_variation(ZmmScales, fjes, 'znunu_over_zmumu{YEAR}_qcd_{VARIATION}Up'.format(YEAR=year-2000, VARIATION=var), "zmm_weights_%s_%s_Up"%(cid, var), _fOut)
    add_variation(ZmmScales, fjes, 'znunu_over_zmumu{YEAR}_qcd_{VARIATION}Down'.format(YEAR=year-2000, VARIATION=var), "zmm_weights_%s_%s_Down"%(cid, var), _fOut)
    CRs[1].add_nuisance_shape(var,_fOut, functype='quadratic')

    add_variation(ZeeScales, fjes, 'znunu_over_zee{YEAR}_qcd_{VARIATION}Up'.format(YEAR=year-2000, VARIATION=var), "zee_weights_%s_%s_Up"%(cid, var), _fOut)
    add_variation(ZeeScales, fjes, 'znunu_over_zee{YEAR}_qcd_{VARIATION}Down'.format(YEAR=year-2000, VARIATION=var), "zee_weights_%s_%s_Down"%(cid, var), _fOut)
    CRs[2].add_nuisance_shape(var,_fOut, functype='quadratic')

    add_variation(PhotonScales, fjes, 'znunu_over_gjets{YEAR}_qcd_{VARIATION}Up'.format(YEAR=year-2000, VARIATION=var), "photon_weights_%s_%s_Up"%(cid, var), _fOut)
    add_variation(PhotonScales, fjes, 'znunu_over_gjets{YEAR}_qcd_{VARIATION}Down'.format(YEAR=year-2000, VARIATION=var), "photon_weights_%s_%s_Down"%(cid, var), _fOut)
    CRs[0].add_nuisance_shape(var,_fOut, functype='quadratic')

  # Photon scale
  fphotonscale = ROOT.TFile("sys/photon_scale_unc.root")
  var = "photon_scale_%s"%year
  add_variation(
                PhotonScales,
                fphotonscale,
                'photon_pt_scale_{CHANNEL}_0.02_up'.format(**filler),
                "photon_weights_%s_%s_Up"%(cid, var),
                _fOut,
                invert=True,
                scale=0.5
                )
  add_variation(
                PhotonScales,
                fphotonscale,
                'photon_pt_scale_{CHANNEL}_0.02_dn'.format(**filler),
                "photon_weights_%s_%s_Down"%(cid, var),
                _fOut,
                invert=True,
                scale=0.5
                )
  CRs[0].add_nuisance_shape(var, _fOut, functype='quadratic')




  cat = Category(model,cid,nam,_fin,_fOut,_wspace,out_ws,_bins,metname,target.GetName(),CRs,diag)
  # Return of course
  return cat