Beispiel #1
0
    hist['sig_'+branchname].SetFillColor(4); hist['sig_'+branchname].SetLineColor(4); hist['sig_'+branchname].SetMarkerColor(4); 
    hist['bkg_'+branchname].SetFillColor(2); hist['bkg_'+branchname].SetLineColor(2);  hist['bkg_'+branchname].SetMarkerColor(2);  
    leg1.Clear()
    leg1.AddEntry(hist["sig_" + branchname],"W jets","l");    leg1.AddEntry(hist["bkg_" + branchname],"QCD jets","l");
    hist['sig_' + branchname].Rebin(10)
    hist['bkg_' + branchname].Rebin(10)
    if (hist['sig_'+branchname].GetMaximum() > hist['bkg_'+branchname].GetMaximum()):
        fn.drawHists(hist['sig_' + branchname], hist['bkg_' + branchname])

    else:
        fn.drawHists(hist['bkg_' + branchname], hist['sig_' + branchname])
    leg1.Draw()
    #if branchname.find('pt') != -1:
    #    fn.pTReweight(hist['sig_'+branchname], hist['bkg_'+branchname], Algorithm+fileid, varBinPt, xbins)
    fn.addLatex(fn.getAlgorithmString(),fn.getAlgorithmSettings(),ptrange, fn.getE(), [nvtxlow, nvtx])
    p = canv1.cd(index+1).Clone()
    tc = TCanvas(branchname)
    p.SetPad(0,0,1,1) # resize
    p.Draw()
    tc.SaveAs(varpath+branchname+".png")

    canv2.cd()
    if index==0:
        roc[branchname].GetXaxis().SetTitle("Efficiency_{W jets}")
        roc[branchname].GetYaxis().SetTitle("1 - Efficiency_{QCD jets}")
        roc[branchname].Draw("al")        
    else:
        roc[branchname].SetLineColor(index+2)
        roc[branchname].Draw("same")
    leg2.AddEntry(roc[branchname],branchname,"l");
Beispiel #2
0
L=CVend-CVini #initial dimensions
#########################################

P1=load_data_range(CV_file,N,CVini,CVend)
print P1.shape
print L
rn=(random.randint(0, L))
print rn
print P1

print '#####################'
#call delrn
P2=delrn(P1,rn)
print P2
#get the error
E=getE(P1,P2)
print E

###############################
#### Monte Carlo
EE=[]
c=[]
E1=1000000.0000
KT=0.01
L
MC=100 #Monte Carlo iterations
for i in range (MC):
	rn=(random.randint(0, L))
	P2=delrn(P1,rn)
	E2=getE(P1,P2)
	E2=E2*(10**6)
Beispiel #3
0
	print L
	OI=[]
	dd=40
	for i in range(dd,L):
		print i

	EF=[]
	deletedCVs=[]
	for i in range(L-1):
		if i==0:
			Plast=P1

		#get maximal
        	for j in range (i,L):
                	Ptmp=delrn(Plast,j-i)
                	Etmp=getE(P1,Ptmp)
			if j==i:
				maxE=Etmp
				max_index=i
			else:
				if Etmp>maxE:
					maxE=Etmp
					max_index=j
	
		EE=[]
		minE=maxE
		
		for j in range (i,L):
			PP=delrn(Plast,j-i)
			E=getE(P1,PP)
			if E<minE:
Beispiel #4
0
def writeResponsePlots(weightedxAOD, Algorithm, plotconfig, trees, cutstring, fileid, ptreweight = True, varpath = "", mass_min = "0.0", mass_max = "1200000.0", scaleLumi = 1, applyMassWindow = True):
    '''
    Run through the Algorithm for a given mass range.  Returns the bkg rej at 50% signal eff.
    Keyword args:
    weightedxAOD -- bool indicating if the xaod is already weighted.
    Algorithm -- Name of the algorithm.  Set in main, comes from config file.
    plotconfig -- Contains the settings for the plot like bin number and hist limits. The key of the dict is the variable name.
    trees -- contains the actual data.
    cutstring -- basic selection cuts to be applied.
    fileid -- File identifier that gets used in the output file names
    ptreweight -- Reweight signal according to pT
    varpath -- Output directory
    mass_min -- Mass window minimum
    mass_max -- Mass window maximum
    scaleLumi -- luminosity scale factor
    applyMassWindow -- Whether or not to apply the 68% mass window cut when plotting.

    Writes out the response distributions for signal and background and then returns the dictionary of histograms.
    '''

    #global weightedxAOD
    hist = {}
    variables = []
    # remove all of the leading underscores
    for x, v in enumerate(plotconfig.keys()):
        stub = plotconfig[v][STUB]
        if not plotconfig[v][1] == True: # if it is not a jet variable
            continue
        if stub.startswith('_'):
            stub = stub[1:]
        variables.append(stub)

    # create all of the histograms
    for typename in ['sig','bkg']:
        histnamestub = typename + '_jet_' + Algorithm + '_response' 
        for br in plotconfig.keys(): # variable names
            if plotconfig[br][1] == True: # if it is a jet variable
                histname = histnamestub+plotconfig[br][STUB]
            else:
                continue
            hist_title = br
            hist[histname] = TH1D(histname, hist_title, 100, 0, 4)#plotconfig[br][MINX], plotconfig[br][MAXX])
            hist[histname].SetYTitle("Normalised Entries")
            hist[histname].SetXTitle("response " + br)
  


    # set the cutstring
    if applyMassWindow:
        cutstring_mass = cutstring+ " * (jet_" +Algorithm + "_m <= " +mass_max+ ")" + " * (jet_" +Algorithm + "_m > " +mass_min+ ") " 
    else:
        cutstring_mass = cutstring

    # the colours for the background and signal
    col_sig = 4
    col_bkg = 2

    # loop through all of the variables
    for index, branchname in enumerate(variables):
        col = 1
        responseName = "jet_" +Algorithm+'_response_' + branchname
        # loop through the background and signal input trees
        for indexin, datatype in enumerate(trees):
            histname =  datatype + "_jet_" +Algorithm+'_response_' + branchname
            varexp = 'response_'+branchname + '>>' + histname
            # the weights are stored in the ntuple for the weighted xAODs.
            if not weightedxAOD:
                cutstringandweight = '*mc_event_weight*1./NEvents(mc_channel_number)'
            else:
                cutstringandweight = '*mc_event_weight*1./evt_nEvts'
            # add the cross section and filter efficiency for the background            
            if datatype == 'bkg': 
                # according to Chris we don't apply the kfactor
                if not weightedxAOD:
                    cutstringandweight += '*filter_eff*xs'#*k_factor'
                else:
                    cutstringandweight += '*evt_filtereff*evt_xsec'#*evt_kfactor'
                hist[histname].SetMarkerStyle(21)
                col = col_bkg
            # filter efficiency for signal
            elif datatype == 'sig':
                # according to Chris we do not apply any of these to signal
                # so reset the cutstring
                cutstringandweight = ''
                #if not weightedxAOD:
                #    cutstringandweight += '*filter_eff'
                #else:
                #    cutstringandweight += '*evt_filtereff'
                # apply pt reweighting to the signal
                if ptreweight:
                    cutstringandweight +='*SignalPtWeight3(jet_CamKt12Truth_pt)'

                col = col_sig
            
            hist[histname].Sumw2();
            #apply the selection.
            trees[datatype].Draw(varexp,cutstring_mass+cutstringandweight)
            # scale the histogram
            if hist[histname].Integral() > 0.0:
                if scaleLumi != 1:
                    hist[histname].Scale(scaleLumi);
                else:
                    hist[histname].Scale(1.0/hist[histname].Integral());
            # set the style for the histogram.
            hist[histname].SetLineStyle(1); hist[histname].SetFillStyle(0); hist[histname].SetMarkerSize(1);
            hist[histname].SetFillColor(col); hist[histname].SetLineColor(col); hist[histname].SetMarkerColor(col); 
        # need to clear leg1
        # create a tlegend to go on the plot
        leg1 = TLegend(0.8,0.55,0.9,0.65);leg1.SetFillColor(kWhite)
        leg1.AddEntry(hist["sig_" + responseName],"W jets","l");    leg1.AddEntry(hist["bkg_" + responseName],"QCD jets","l");
        # plot the maximum histogram
        canv1 = TCanvas("tempCanvas")
        if (hist['sig_'+responseName].GetMaximum() > hist['bkg_'+responseName].GetMaximum()):
            fn.drawHists(hist['sig_' + responseName], hist['bkg_' + responseName])
        else:
            fn.drawHists(hist['bkg_' + responseName], hist['sig_' + responseName])
        leg1.Draw()

        # add correctly formatted text to the plot for the ATLAS collab text, energy, etc.
        fn.addLatex(fn.getAlgorithmString(),fn.getAlgorithmSettings(),fn.getPtRange(), fn.getE(), [fn.getNvtxLow(), fn.getNvtx()])
        # save individual plots
        if applyMassWindow:
            canv1.SaveAs(varpath+responseName+".png")
        else:
            canv1.SaveAs(varpath+responseName+"_noMW.png")

        del canv1
    return hist
Beispiel #5
0
def analyse(Algorithm, plotbranches, plotreverselookup, plotconfig, trees, cutstring, hist, leg1, leg2, fileid, records, ptreweight = True, varpath = "", savePlots = True, mass_min = "0.0", mass_max = "1200000.0", scaleLumi = 1, nTracks='999'):
    '''
    Run through the Algorithm for a given mass range.  Returns the bkg rej at 50% signal eff.
    Keyword args:
    Algorithm -- Name of the algorithm.  Set in main, comes from config file.
    plotbranches -- the variables to be plotted.  Set in main.
    plotreverselookup -- Lookup for an algorithm from a variable stub
    plotconfig --- Dictionary of the plotting arguments for different variables.
    trees -- contains the actual data.
    cutstring -- basic selection cuts to be applied.
    hist -- Histograms that will be filled/ saved.
    leg1 -- TLegend for histograms
    leg2 -- TLegend for ROC curves
    fileid -- File identifier that gets used in the output file names
    ptreweight -- Reweight signal according to pT
    varpath -- output folder to save single variable plots to
    saveplots -- whether or not to write out plots to file
    mass_min -- Mass window minimum
    mass_max -- Mass window maximum
    scaleLumi -- luminosity scale factor
    nTracks -- cut on NTracks to apply.  Default is 999 which is essentially no cut.

    Returns:
    Background rejection at 50% signal efficiency using the ROC curve and variable used to achieve maximum rejection.
    '''

    # open log file
    #logfile = open(records,'w')
    cutflow = open(records.replace('.out','.cutflow'),'w')

    # canvas for histogram plots
    canv1 = TCanvas("canv1")
    canv1.Divide(5,5)
    # canvas for rejection ROC curves
    canv2 = TCanvas("canv2", "ROC curves showing 1-background rejection vs signal efficiency")
    # canvas for power roc curves
    power_canv = TCanvas('powercurves',"ROC curves showing background rejection power vs signal efficiency")
    power_canv.SetLogy()
    power_legend = TLegend(0.6,0.5,0.9,0.9); power_legend.SetFillColor(kWhite);

    tempCanv = TCanvas("temp")
    # reset hists
    for h in hist.keys():
        hist[h].Reset()
    
    global weightedxAOD
    global singleSidedROC

    global totalrejection
    # dict containing all of the ROC curves
    roc={}
    roc_nomw = {}
    bkgRejROC= {}
    bkgPowerROC = {}
    # bool that is set to false if no ROC curves are drawn - this will happen if any 
    # hist added to the roc is empty
    writeROC = False

    # dictionary containing the 50% signal eff bkg rejection power
    roc_rejection_scores = {}

    # dictionary holding all of the histograms without a mass cut
    hist_nomw = {}
    saveNoMassWindowPlots = savePlots
    hist_mass_nomw = {}

    # record the integral of pt for mw and nomw
    mw_int_pt = {}
    full_int_pt = {}

    # maximum rejection
    maxrej = 0
    maxrejvar = ''
    #set up the cutstring/ selection to cut on the correct jet masses
    cutstring_mass = cutstring+ " * (jet_" +Algorithm + "_m <= " +mass_max+ ")" + " * (jet_" +Algorithm + "_m > " +mass_min+ ") " 
    # loop through the indices and branchnames
    for index, branchname in enumerate(plotbranches):
        # add ROC dictionary entry
        roc[branchname] = TGraph()#Errors()
        roc[branchname].SetTitle(branchname)
        roc[branchname].SetName('roc_'+branchname)
        roc_nomw[branchname] = TGraph()#Errors()
        roc_nomw[branchname].SetTitle('No mass window ' + branchname)
        roc_nomw[branchname].SetName('roc_nomw_'+branchname)
        # add bkg rej power dictionary entry
        bkgRejROC[branchname] = TGraph()#Errors()
        bkgRejROC[branchname].SetTitle(branchname)
        bkgRejROC[branchname].SetName('bkgrej_roc_'+branchname)
        bkgPowerROC[branchname] = TGraph()#Errors()
        bkgPowerROC[branchname].SetTitle(branchname)
        bkgPowerROC[branchname].SetName('bkgpower_roc_'+branchname)
        # new canvas
        canv1.cd(index+1)

        # keep the integral when not applying mass window cuts, this
        # allows us to calculate the efficiency of the mass window cut
        signal_eff = 1.0
        bkg_eff = 1.0

        # setting the maximum of the plot - normally multiply by 1.2, but for some, like tauwta21 must be higher
        max_multiplier = 1.2
        if branchname.lower().find('tauwta2tauwta1') != -1:
            max_multiplier = 1.25


        # loop through the datatypes: signal and background
        for indexin, datatype in enumerate(trees):
            canv1.cd(index+1)
            histname =  datatype + "_" + branchname

            print "plotting " + datatype + branchname
            #logfile.write("plotting " + datatype + branchname+"\n")


            minxaxis = hist[histname].GetXaxis().GetXmin()
            maxxaxis = hist[histname].GetXaxis().GetXmax()
            # add the mc_weight and weighted number of events to the selection string
            # also make sure that the variable being plotted is within the bounds specified 
            # in the config file (the limits on the histogram)
            if not weightedxAOD:
                cutstringandweight = '*mc_event_weight*1./NEvents(mc_channel_number)'
            else:
                cutstringandweight = '*mc_event_weight*1./evt_nEvts'

            # add the cross section and filter efficiency for the background
            
            if datatype == 'bkg': 
                # no longer apply the k factor
                if not weightedxAOD:
                    cutstringandweight += '*filter_eff*xs'#*k_factor'
                else:
                    cutstringandweight += '*evt_filtereff*evt_xsec'#*evt_kfactor'
                hist[histname].SetMarkerStyle(21)
            # filter efficiency for signal
            elif datatype == 'sig':
                # we only apply pt rw now, so reset the cutstring
                cutstringandweight=''
                # apply pt reweighting to the signal
                if ptreweight:
                    cutstringandweight +='*SignalPtWeight3(jet_CamKt12Truth_pt)'
            
            hist[histname].Sumw2();
            # set up the tree.Draw() variable expression for the histogram
            varexp = branchname + '>>' + histname
            # apply the selection to the tree and store the output in the histogram
            if branchname.find('_m')==-1:
                trees[datatype].Draw(varexp,cutstring_mass+cutstringandweight)#+'*(nTracks<'+nTracks+')')
            else:
                trees[datatype].Draw(varexp,cutstring+cutstringandweight)#+'*(nTracks<'+nTracks+')')

            # if the histogram is not empty then normalise it
            
            #mw_int = hist[histname].Integral()

            if hist[histname].Integral() > 0.0:
                if scaleLumi != 1:
                    hist[histname].Scale(scaleLumi);
                else:
                    hist[histname].Scale(1.0/hist[histname].Integral());


            # set up the axes titles and colours/ styles
            hist[histname].SetLineStyle(1); hist[histname].SetFillStyle(0); hist[histname].SetMarkerSize(1);
            if (branchname.find('jet_')!=-1):
                hist[histname].SetXTitle(plotreverselookup[branchname.replace("jet_"+Algorithm,"")])
            else:
                hist[histname].SetXTitle(plotreverselookup[branchname])
            hist[histname].SetYTitle("Normalised Entries")

            #now get the same plot for no mass window cut to get the eff
            hist_full_massonly = hist[histname].Clone()
            hist_full_massonly.Reset()
            hist_full_massonly.SetName(histname+'_massonly')
            # need to store the variable in this histogram
            varexpfull = branchname + ' >>' + histname+'_massonly'
            # no nTracks cut here!!!!
            if branchname.find('_m')==-1:
                trees[datatype].Draw(varexpfull,cutstring_mass+cutstringandweight)
            else:
                trees[datatype].Draw(varexpfull,cutstring+cutstringandweight)
            # get the integral and normalise
            mw_int = hist_full_massonly.Integral()
            
            hist_full_massonly.Reset()
            hist_full_massonly.SetName(histname+'_full_massonly')
            # need to store the variable in this histogram
            varexpfull = branchname + ' >>' + histname+'_full_massonly'
            # no nTracks cut here!!!!
            trees[datatype].Draw(varexpfull,cutstring+cutstringandweight+"*(jet_" +Algorithm + "_m < 1200*1000)" + " * (jet_" +Algorithm + "_m > 0)")
            # get the integral and normalise
            full_int = hist_full_massonly.Integral()

            
            if histname.find('_pt') != -1:
                mw_int_pt[datatype] = mw_int
                full_int_pt[datatype] = full_int


            #now get the same plot for no mass window cut to get the eff
            hist_full = hist[histname].Clone()
            hist_full.Reset()
            hist_full.SetName(histname+'_full')
            # need to store the variable in this histogram
            varexpfull = branchname + ' >>' + histname+'_full'

            trees[datatype].Draw(varexpfull,cutstring+cutstringandweight+"*(jet_" +Algorithm + "_m < 1200*1000)" + " * (jet_" +Algorithm + "_m > 0)")#+'*(nTracks<'+nTracks+')')
            histInt = hist_full.Integral()
            # now scale
            if histInt != 0.0:
                if scaleLumi!=1:
                    hist_full.Scale(scaleLumi)
                else:
                    hist_full.Scale(1./histInt)
            # change the x title
            hist_full.SetXTitle(hist[histname].GetXaxis().GetTitle()+' (no mass window)')

            #save this histogram to the no mass window histo dictionary
            hist_nomw[histname+'_full'] = hist_full.Clone()

            if False:#datatype == 'sig':
                if full_int !=0:
                    signal_eff = float(mw_int/full_int)
                else:
                    signal_eff = 0.0
            if False:#else:
                if full_int != 0:
                    bkg_eff = float(mw_int/full_int)
                else:
                    bkg_eff = 0.0

        #Make ROC Curves before rebinning, but only if neither of the samples are zero
        if (hist["sig_" +branchname].Integral() != 0 and hist["bkg_" +branchname].Integral() != 0):

            if singleSidedROC == 'M':
                # check where the median is so we can correctly choose L or R cut.
                sig_median = fn.median(hist['sig_'+branchname])
                bkg_median = fn.median(hist['bkg_'+branchname])

                if sig_median > bkg_median:
                    side = 'R'
                else:
                    side = 'L'

                roc[branchname] = fn.RocCurve_SingleSided(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=side)

                #roc[branchname],hsigreg50,hcutval50,hsigreg25,hcutval25 = fn.RocCurve_SingleSided_WithUncer(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=side)
                bkgRejROC[branchname] = roc[branchname]
                bkgPowerROC[branchname] = fn.RocCurve_SingleSided(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=side,rejection=False)
                

            elif singleSidedROC == 'L' or singleSidedROC == 'R':
                roc[branchname] = fn.RocCurve_SingleSided(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=singleSidedROC)
                #roc[branchname],hsigreg50,hcutval50,hsigreg25,hcutval25 = fn.RocCurve_SingleSided_WithUncer(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=singleSidedROC)
                bkgRejROC[branchname] = roc[branchname]
                bkgPowerROC[branchname] = fn.RocCurve_SingleSided(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside=singleSidedROC,rejection=False)

            else:
                MakeROCBen(1, hist["sig_" +branchname], hist["bkg_" +branchname], roc[branchname], bkgRejROC[branchname], signal_eff, bkg_eff)
                bkgPowerROC[branchname] = fn.RocCurve_SingleSided(hist["sig_" +branchname], hist["bkg_" +branchname], signal_eff, bkg_eff, cutside='R',rejection=False)
            writeROC = True
            
        canv1.cd(index+1)
        pX = Double(0.5)
        pY = Double(0.0)

        # find the corresponding bkg rejection for the 50% signal efficiency point from bkg rejection power ROC curve
        # However, if we want the background rejection power for the mass variable we do not want to take 50% as we already have made
        # a cut on the mass to get it to 68%.
        # calculate error on this as well -> deltaX = X*(deltaY/Y)
        eval_roc = 1.0
        err_up = 1
        err_do = 1
        if not branchname.endswith("_m"):
            #eval_roc = roc[branchname].Eval(0.5)
            eval_roc = fn.GetBGRej50(roc[branchname])
            # get the bin for this point so that we can find the associated error in roc error tgraphs
            #rocBin = fn.findYValue(roc[branchname],Double(0.5), pY, 0.01, True, True)
            bin_num = roc[branchname].GetXaxis().FindBin(0.5)#roc_errUp[branchname].Eval(0.5)
            eval_rocup = eval_roc+roc[branchname].GetErrorX(bin_num)
            eval_rocdo = eval_roc-roc[branchname].GetErrorX(bin_num)
        else:
            #eval_roc = roc[branchname].Eval(0.68)
            eval_roc = fn.GetBGRej(roc[branchname], 0.68)
            #rocBin = fn.findYValue(roc[branchname],Double(0.68), pY, 0.01, True, True)
            bin_num = roc[branchname].GetXaxis().FindBin(0.68)#roc_errUp[branchname].Eval(0.5)
            eval_rocup = eval_roc+roc[branchname].GetErrorX(bin_num)
            eval_rocdo = eval_roc-roc[branchname].GetErrorX(bin_num)

        if eval_roc != 1:
            bkgrej = 1/(1-eval_roc)
        else:
            bkgrej = -1
        
        roc_rejection_scores[branchname] = bkgrej

        if (eval_rocup != 1):
            bkgrej_errUp = abs(bkgrej-1/(1-eval_rocup))
        else:
            bkgrej_errUp = -1
        if (eval_rocdo!= 1):
            bkgrej_errDo = abs(bkgrej-1/(1-eval_rocdo))
        else:
            bkgrej_errDo = -1

        # store a record of all background rejection values
        # want to store only the variable name, not the algorithm name, so string manipulation.  here it is stored as sig_jet_ALGO_variable.
        groups = branchname.split('_')
        j = '_'.join(groups[:2]), '_'.join(groups[2:])

        if not j[1] == 'pt':
            totalrejection.append([j[1], float(bkgrej), float(bkgrej_errUp), float(bkgrej_errDo)])

        if bkgrej > maxrej:
            maxrej = bkgrej
            maxrejvar = branchname

        # once the background rejection power has been calculated using the 200 bins the histograms can be rebinned.
            
        hist['sig_'+branchname].SetFillColor(4); hist['sig_'+branchname].SetLineColor(4); hist['sig_'+branchname].SetMarkerColor(4); hist['sig_'+branchname].Rebin(4);
        hist['bkg_'+branchname].SetFillColor(2); hist['bkg_'+branchname].SetLineColor(2);  hist['bkg_'+branchname].SetMarkerColor(2);  hist['bkg_'+branchname].Rebin(4);
        if saveNoMassWindowPlots:
            if singleSidedROC == 'M':
                # check where the median is so we can correctly choose L or R cut.
                sig_median = fn.median(hist_nomw['sig_'+branchname+'_full'])
                bkg_median = fn.median(hist_nomw['bkg_'+branchname+'_full'])

                if sig_median > bkg_median:
                    side = 'R'
                else:
                    side = 'L'
                    
                #roc_nomw[branchname],v1,v2,v3,v4 = fn.RocCurve_SingleSided_WithUncer(hist_nomw["sig_" +branchname+'_full'], hist_nomw["bkg_" +branchname+'_full'], 1,1, cutside=side)
                roc_nomw[branchname] = fn.RocCurve_SingleSided(hist_nomw["sig_" +branchname+'_full'], hist_nomw["bkg_" +branchname+'_full'], 1,1, cutside=side, rejection=True, debug_flag=False)

            elif singleSidedROC == 'L' or singleSidedROC == 'R':
                #roc_nomw[branchname],v1,v2,v3,v4 = fn.RocCurve_SingleSided_WithUncer(hist_nomw["sig_" +branchname+'_full'], hist_nomw["bkg_" +branchname+'_full'], 1,1, cutside=singleSidedROC)
                roc_nomw[branchname] = fn.RocCurve_SingleSided(hist_nomw["sig_" +branchname+'_full'], hist_nomw["bkg_" +branchname+'_full'], 1,1, cutside=singleSidedROC, rejection=True, debug_flag=False)

            else:
                MakeROCBen(1, hist_nomw["sig_" +branchname+'_full'], hist_nomw["bkg_" +branchname+'_full'], roc_nomw[branchname], TGraphErrors(), signal_eff, bkg_eff)
            canv1.cd(index+1)
            #roc_nomw[branchname].GetXaxis().SetTitle("Efficiency_{W jets}")
            #roc_nomw[branchname].GetYaxis().SetTitle("1 - Efficiency_{QCD jets}")
            hist_nomw['sig_'+branchname+'_full'].SetFillColor(4); hist_nomw['sig_'+branchname+'_full'].SetLineColor(4); hist_nomw['sig_'+branchname+'_full'].SetMarkerColor(4); 
            hist_nomw['bkg_'+branchname+'_full'].SetFillColor(2); hist_nomw['bkg_'+branchname+'_full'].SetLineColor(2);  hist_nomw['bkg_'+branchname+'_full'].SetMarkerColor(2);
            # resize the mass plots to be in a better range
            if branchname.endswith('_m'):
                hist['sig_'+branchname].SetAxisRange(0.0,300.0*1000.0)
                hist['bkg_'+branchname].SetAxisRange(0.0,300.0*1000.0)
                hist['sig_'+branchname].GetXaxis().SetLimits(0.0,300.0)
                hist['bkg_'+branchname].GetXaxis().SetLimits(0.0,300.0)
            else:
                hist_nomw['sig_'+branchname + '_full'].Rebin(4);
                hist_nomw['bkg_'+branchname + '_full'].Rebin(4);

        leg1.Clear()
        # add legend entries for bkg and signal histograms
        leg1.AddEntry(hist["sig_" + branchname],"W jets","l");    leg1.AddEntry(hist["bkg_" + branchname],"QCD jets","l");

        y_high = max(hist['sig_'+branchname].GetMaximum(), hist['bkg_'+branchname].GetMaximum())
        hist['bkg_'+branchname].SetMaximum(y_high*max_multiplier);hist['sig_'+branchname].SetMaximum(y_high*max_multiplier)
        # plot the maximum histogram
        #if (hist['sig_'+branchname].GetMaximum() > hist['bkg_'+branchname].GetMaximum()):
        fn.drawHists(hist['sig_' + branchname], hist['bkg_' + branchname])
        # else:
        #    fn.drawHists(hist['bkg_' + branchname], hist['sig_' + branchname])
        # change the coordinates to LHS of the canvas if we are plotting ThrustMaj or YFilt.
        offset_x = False
        if branchname.lower().find('thrustmaj')!=-1 or branchname.lower().find('yfilt')!=-1:
            offset_x = True
            leg1.SetX1NDC(0.25)
            leg1.SetX2NDC(0.35)
        else:
            leg1.SetX1NDC(0.8)
            leg1.SetX2NDC(0.9)
        leg1.Draw("same")

        # add correctly formatted text to the plot for the ATLAS collab text, energy, etc.
        fn.addLatex(fn.getAlgorithmString(),fn.getAlgorithmSettings(),fn.getPtRange(), fn.getE(), [fn.getNvtxLow(), fn.getNvtx()], offset_x)
        # save individual plots
        if savePlots:
            p = canv1.cd(index+1).Clone() 
            tempCanv.cd()
            p.SetPad(0,0,1,1) # resize
            p.Draw()
            tempCanv.SaveAs(varpath+branchname+".pdf")
            #tempCanv.SaveAs(varpath+branchname+".eps")
            del p

        # now save "no mass window" plots
        if saveNoMassWindowPlots:
            # resize the mass plots to be in a better range
            if branchname.find('_m') != -1:
                hist_nomw['sig_'+branchname+'_full'].SetAxisRange(0.0,300.0*1000.0)
                hist_nomw['sig_'+branchname+'_full'].GetXaxis().SetRangeUser(0.0,1000.0*300.0)
                hist_nomw['sig_'+branchname+'_full'].GetXaxis().SetLimits(0.0,300.0)
                hist_nomw['bkg_'+branchname+'_full'].SetAxisRange(0.0,300.0*1000.0)
                hist_nomw['bkg_'+branchname+'_full'].GetXaxis().SetRangeUser(0.0,1000.0*300.0)
                hist_nomw['bkg_'+branchname+'_full'].GetXaxis().SetLimits(0.0,300.0)
            tempCanv2 = TCanvas("tempnomw"+branchname)
            tempCanv2.cd()
            y_high = max(hist_nomw['sig_'+branchname+'_full'].GetMaximum(), hist_nomw['bkg_'+branchname+'_full'].GetMaximum())
            y_low = 0.0 #min(hist_nomw['sig_'+branchname+'_full'].GetMinimum(), hist_nomw['bkg_'+branchname+'_full'].GetMaximum())
            hist_nomw['bkg_'+branchname+'_full'].SetMaximum(y_high*max_multiplier);hist_nomw['sig_'+branchname+'_full'].SetMaximum(y_high*max_multiplier)
            #if (hist_nomw['sig_'+branchname+'_full'].GetMaximum() > hist_nomw['bkg_'+branchname+'_full'].GetMaximum()):
            fn.drawHists(hist_nomw['sig_' + branchname+'_full'], hist_nomw['bkg_' + branchname+'_full'])
            #else:
            #    fn.drawHists(hist_nomw['bkg_' + branchname+'_full'], hist_nomw['sig_' + branchname+'_full'])

            offset_x = False
            if branchname.lower().find('thrustmaj')!=-1 or branchname.lower().find('yfilt')!=-1:
                offset_x = True
                leg1.SetX1NDC(0.25)
                leg1.SetX2NDC(0.35)
            else:
                leg1.SetX1NDC(0.8)
                leg1.SetX2NDC(0.9)
            leg1.Draw("same")

            # if we are doing the mass plt we want to indicate the mass window
            if branchname.find('_m') == -1:
                mrange = []
            else:
                mrange = [float(mass_min), float(mass_max)]
                # if it is the mass variable then draw lines indicating the mass window
                line_min = TLine(float(mass_min)/1000.0, y_low, float(mass_min)/1000.0, y_high); line_min.SetLineColor(kBlack);
                line_max = TLine(float(mass_max)/1000.0, y_low, float(mass_max)/1000.0, y_high); line_max.SetLineColor(kBlack);
                line_min.Draw('same')
                line_max.Draw('same')

            # add the latex parts to the plot -> ATLAS, tev range, etc.
            fn.addLatex(fn.getAlgorithmString(),fn.getAlgorithmSettings(),fn.getPtRange(), fn.getE(), [fn.getNvtxLow(), fn.getNvtx()], offset_x, massrange = mrange)

            tempCanv2.SaveAs(varpath+branchname+"_noMW.pdf")
            #tempCanv2.SaveAs(varpath+branchname+"_noMW.eps")
            del tempCanv2

        
        canv1.cd(index+1)

    min_roc = 1.0
    for b in roc.keys():
        if b.find('_m') == -1 and b.find('_pt') == -1:
            n = roc[b].GetN()
            y = roc[b].GetY()
            locmin = TMath.LocMin(n,y)
            minval = y[locmin]
            min_roc = min(min_roc, minval)
            
    for branchidx, branchname in enumerate(roc.keys()):
        # plot the ROC curves
        canv2.cd()
        roc[branchname].GetXaxis().SetTitle("Efficiency_{W jets}")
        roc[branchname].GetYaxis().SetTitle("1 - Efficiency_{QCD jets}")
        roc[branchname].SetMinimum(min_roc*0.98)
        bkgPowerROC[branchname].GetXaxis().SetTitle("Efficiency_{W jets}")
        bkgPowerROC[branchname].GetYaxis().SetTitle("1/Efficiency_{QCD jets}")
    

        # only plot the roc and power curves if this is not a mass
        if branchname.find('_m') == -1 and branchname.find('_pt') == -1:
            roc[branchname].SetLineStyle(branchidx%10)
            if branchidx==0 and roc[branchname].Integral() != 0:
                roc[branchname].Draw("al")        
            elif roc[branchname].Integral() != 0:
                roc[branchname].SetLineColor(colours[branchidx])
                roc[branchname].Draw("same")
                # legend for the roc curve
            leg2.AddEntry(roc[branchname],branchname,"l");
            leg2.Draw("same")

            # plot the power curves
            power_canv.cd()
            bkgPowerROC[branchname].SetLineStyle(branchidx%10)
            if branchidx==0 and bkgPowerROC[branchname].Integral() != 0:
                bkgPowerROC[branchname].Draw("al")        
            elif bkgPowerROC[branchname].Integral() != 0:
                bkgPowerROC[branchname].SetLineColor(colours[branchidx])
                bkgPowerROC[branchname].Draw("same")
            power_legend.AddEntry(bkgPowerROC[branchname],branchname,'l')
            power_legend.Draw('same')

    # write out canv1 and roc curves on one page/ png each
    if savePlots:
        #write out the plots after cuts
        writePlots(Algorithm, fileid, canv1, canv2, writeROC, roc, power_canv)
        writePlotsToROOT(Algorithm, fileid, hist, roc, bkgRejROC, roc_nomw, roc_rejection_scores, recreate=True, power_curves = bkgPowerROC)
        #responseHists = resp.writeResponsePlots(weightedxAOD, Algorithm, plotconfig, trees, cutstring, fileid, ptreweight, varpath, mass_min, mass_max, scaleLumi)
        #responseHists = resp.writeResponsePlots(weightedxAOD, Algorithm, plotconfig, trees, cutstring, fileid, ptreweight, varpath, mass_min, mass_max, scaleLumi, applyMassWindow=False)
        #writePlotsToROOT(Algorithm, fileid, hist, recreate=False)

    # write out event counts for mass window cuts (not weighted)
    cutflow.write('Signal:\njet selection no mass window: '+'pt' +' '+ str(hist_nomw['sig_jet_'+Algorithm+'_pt_full'].GetEntries())+'\n')
    if 'sig' in full_int_pt.keys():
        cutflow.write('jet selection no mass window: '+'pt weighted '+ str(full_int_pt['sig'])+'\n')
    cutflow.write('mass window and jet selection: pt ' + str(hist['sig_jet_'+Algorithm+'_pt'].GetEntries())+'\n')
    if 'sig' in mw_int_pt.keys():
        cutflow.write('mass window and jet selection: pt weighted ' + str(mw_int_pt['sig'])+'\n')
    cutflow.write('Background:\njet selection no mass window: pt '+ str(hist_nomw['bkg_jet_'+Algorithm+'_pt_full'].GetEntries())+'\n')
    if 'bkg' in full_int_pt.keys():
        cutflow.write('jet selection no mass window: pt weighted '+ str(full_int_pt['bkg'])+'\n')
    cutflow.write('mass window and jet selection: pt ' + str(hist['bkg_jet_'+Algorithm+'_pt'].GetEntries())+'\n')
    if 'bkg' in mw_int_pt.keys():
        cutflow.write('mass window and jet selection: pt weighted ' + str(mw_int_pt['bkg'])+'\n')
    # close logfile
    cutflow.close()

    # return the variable with the maximum background rejection
    return maxrej, maxrejvar