def injectDataLikeSignal(args): print '\n******************************************' print 'inject data-like signal' #****************************************** #set ATLAS style #Yvonne hacking this #using the python version #just import the python one later if os.path.isfile(os.path.expanduser("/lustre/SCRATCH/atlas/ywng/WorkSpace/signalInjection/20171122_SensitivityScan/PlotSensitivity/RootStyle/AtlasStyle.C")): ROOT.gROOT.LoadMacro('/lustre/SCRATCH/atlas/ywng/WorkSpace/signalInjection/20171122_SensitivityScan/PlotSensitivity/RootStyle/AtlasStyle.C') #ROOT.set_color_env() #if os.path.isfile(os.path.expanduser('~/RootUtils/AtlasStyle.C')): # ROOT.gROOT.LoadMacro('~/RootUtils/AtlasStyle.C') # ROOT.SetAtlasStyle() # #ROOT.set_color_env() else: print '\n***WARNING*** couldn\'t find ATLAS Style' #import AtlasStyle #AtlasStyle.SetAtlasStyle() #------------------------------------------ #set error sum and overflow ROOT.TH1.SetDefaultSumw2() ROOT.TH1.StatOverflows() ROOT.TH2.SetDefaultSumw2() ROOT.TH2.StatOverflows() #------------------------------------------ #input parameters print '\ninput parameters:' argsdict = vars(args) for ii in xrange(len(argsdict)): print ' %s = %s'%(argsdict.keys()[ii], argsdict.values()[ii],) slumi = ('%.1f'% float( str(args.lumi).replace('p','.'))).replace('.','p') #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #get settings print '\nconfig settings:' settings = ROOT.TEnv() if settings.ReadFile(args.configFileName,ROOT.EEnvLevel(0)) != 0: raise IOError('could not find sensitivity scan config file: %s'%args.configFileName) model = settings.GetValue('signalModel','') print ' signal model = %s'%model modelLabel = settings.GetValue('signalModelLabel','').replace('"','') print ' signal model label = %s'%modelLabel massValuesConfig = settings.GetValue('signalMasses','2000,3000,4000').split(',') massValuesConfig = [float(m) for m in massValuesConfig] print ' signal masses [GeV] = %s'%massValuesConfig histBaseNameBkg = settings.GetValue('histBaseNameBkg','mjj') print ' hist base name = %s'%histBaseNameBkg histBaseNameSig = settings.GetValue('histBaseNameSig','mjj') print ' hist base name = %s'%histBaseNameSig bTaggingWP = settings.GetValue('bTaggingWP','') #fix_8585 print ' b-tagging WP = %s'%bTaggingWP axisLabel = settings.GetValue('axisLabel','m [GeV]') print ' hist x-axis label = %s'%axisLabel nPar = int(settings.GetValue('nFitParameters','3')) print ' n fit parameters = %s'%nPar thresholdMass = float(settings.GetValue('thresholdMass','1100.')) print ' threshold mass = %s'%thresholdMass seed = float(settings.GetValue('randomSeed','0')) print ' random seed = %s'%seed configNotes = settings.GetValue('notes','').split(',') print ' notes = %s'%configNotes #------------------------------------------ #set variables slumi = ('%.1f'% float( str(args.lumi).replace('p','.'))).replace('.','p') histNameSig = histBaseNameSig histNameBkg = histBaseNameBkg print("Step2 histNameBkg: ", histNameBkg) if bTaggingWP != '': histNameBkg+='_'+bTaggingWP if args.debug: print '\nhist name = %s'%histNameBkg textSize=20 #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #check data-like QCD file if not os.path.isfile(args.dataLikeQCDFileName): raise SystemExit('\n***ERROR*** couldn\'t find data-like QCD file: %s'%args.dataLikeQCDFileName) #------------------------------------------ #check luminosity #if not slumi+'.ifb.' in args.dataLikeQCDFileName: #HANNO: commented out # raise SystemExit('\n***ERROR*** is the lumi value right?') #------------------------------------------ #check output file #outFileName = localdir+'/../results/signalplusbackground/signalplusbackground.'+model+'.'+slumi+'.ifb.'+histNameSig+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' histNameFromInput=histNameSig.format("") outFileName = localdir+'/../results2/signalplusbackground/signalplusbackground.'+model+"."+slumi+'.ifb.'+histNameFromInput+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' #if os.path.isfile(outFileName): # raise SystemExit('\n***WARNING*** output file exists already: %s'%outFileName) outFile = ROOT.TFile(outFileName, 'RECREATE') #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #data-like QCD hist dataLikeQCDFile = ROOT.TFile(args.dataLikeQCDFileName, 'READ') if not dataLikeQCDFile: raise SystemExit('\n***ERROR*** couldn\'t open data-like QCD input file: %s'%args.dataLikeQCDFileName) #QCDHist = dataLikeQCDFile.Get(histName+'_DL') QCDHist = dataLikeQCDFile.Get(histNameBkg) if not QCDHist: raise SystemExit('\n***ERROR*** couldn\'t find data-like QCD input histogram: %s'%histNameBkg) QCDHist.SetName(histNameBkg+'_QCD') print ("histNameBkg: ",histNameBkg) QCDHist.SetTitle(histNameBkg+'_QCD') outFile.cd() QCDHist.Write() #------------------------------------------ #define canvas before entering loop over input signals if args.plot: c1 = ROOT.TCanvas('c1', 'c1', 100, 50, 800, 600) c1.SetLogx(1) c1.SetLogy(1) #------------------------------------------ #get signal samples #fileList = os.listdir(localdir+'/../inputs/'+model+'/') fileList = os.listdir(localdir+'/../inputs/'+'Gauss_width3'+'/') print("sigFiles: ", fileList) for sigFileName in sorted(fileList): #------------------------------------------ #check that it is a valid signal file if not '.root' in sigFileName: continue #------------------------------------------ #get signal mass value from file name mass = sensitivityTools.getSignalMass(sigFileName) print '\n%s: %s GeV'%(model,mass) #check that the signal mass value is contained in the input list of signal masses (config file) #if float(mass) not in massValuesConfig: # print ' skip' # continue #------------------------------------------ #TEST #if float(mass) != 3000.: # continue #------------------------------------------ #get signal hist sigFile = ROOT.TFile(localdir+'/../inputs/'+model+'/'+sigFileName) print("path: ", localdir+'/../inputs/'+model+'/'+sigFileName) print("histNameSig: ", histNameSig) histNameSigUpdated=histNameSig.format(str(mass)) print("histNameSigUpdated: ", histNameSigUpdated) sigHist = sigFile.Get(histNameSigUpdated) print("sigHistIntegral: ", sigHist.Integral()) print(sigHist, sigHist) print("histNameSig: ", histNameSigUpdated) sigHist.SetName(histNameSigUpdated+'_sig') sigHist.SetTitle(histNameSigUpdated+'_sig') if sigHist is not None and args.debug: print '\n signal events: ', sigHist.GetEntries() print ' effective signal events: ', sigHist.GetEffectiveEntries() print ' sum of signal weights: ', sigHist.GetSumOfWeights() #------------------------------------------ #scaled signal hist scaleFactor = float(args.lumi)*1000 #NOTE cross sections are included already ''' if args.fixCS: ZprimebbCrossSection = sensitivityTools.getZprimebbCrossSection(mass) print '\n Z\'->bb cross section applied: %s fb'%ZprimebbCrossSection scaleFactor*=ZprimebbCrossSection ''' if args.debug: print '\n scale factor: %s'%scaleFactor #scale histogram by factor scaledSigHist = sigHist.Clone() scaledSigHist.Scale(scaleFactor) scaledSigHist.SetName(histNameSig+'_scaledSig') if scaledSigHist is not None and args.debug: print '\n events after scaling: ', scaledSigHist.GetEntries() print ' effective entries after scaling: ', scaledSigHist.GetEffectiveEntries() print ' sum of weights after scaling: ', scaledSigHist.GetSumOfWeights() print ' first bin above 0 after scaline: ', scaledSigHist.FindFirstBinAbove(0,1) #------------------------------------------ #effective entries signal hist effEntSigHist = plotTools.getEffectiveEntriesHistogram(sigHist, histNameSig+'_eff') if args.debug: print '\n entries in effective entries: ', effEntSigHist.GetEntries() print ' effective entries in effective entries: ', effEntSigHist.GetEffectiveEntries() print ' sum of weights in effective entries: ', effEntSigHist.GetSumOfWeights() #------------------------------------------ #data-like signal hist histNameSig2=histNameSig.format(str(int(mass))) dataLikeSigHist = plotTools.getDataLikeHist(effEntSigHist, scaledSigHist, histNameSig2+'_sig', seed, thresholdMass) firstBin = -1 for ii in xrange(dataLikeSigHist.GetNbinsX()): if dataLikeSigHist.GetBinContent(ii)>0.: firstBin=ii break if firstBin > 0.: print ' data-like signal histogram starts at %s GeV'%dataLikeSigHist.GetBinLowEdge(firstBin) else: print ' data-like signal histogram is empty: n. entries = %s'%dataLikeSigHist.GetEntries() #------------------------------------------ #smooth signal hist histNameSigSmooth=histNameSig.format(str(int(mass))) smoothSigHist = plotTools.getSmoothHistogram(scaledSigHist, histNameSigSmooth+'_sig_smooth') #------------------------------------------ #remove any signal entry if there are no QCD entries (low mass region) if dataLikeSigHist is not None: for ii in xrange(QCDHist.GetNbinsX()): if QCDHist.GetBinContent(ii) == 0: dataLikeSigHist.SetBinContent(ii,0) dataLikeSigHist.SetBinError(ii,0) smoothSigHist.SetBinContent(ii,0) smoothSigHist.SetBinError(ii,0) else: break #------------------------------------------ #signal+QCD hist if QCDHist is not None and args.debug: print '\n QCD events: ', QCDHist.GetEntries() print ' QCD effective events: ', QCDHist.GetEffectiveEntries() print ' QCD sum of weights: ', QCDHist.GetSumOfWeights() totHist = QCDHist.Clone() #.......................................... #ORIGINAL #if dataLikeSigHist is not None: # totHist.Add(dataLikeSigHist) #.......................................... #NEW if dataLikeSigHist.GetBinContent(ii)>0.: print ' injecting data-like signal' totHist.Add(dataLikeSigHist) else: print ' not enough effective entries: injecting smoooth signal' totHist.Add(smoothSigHist) #END NEW #.......................................... histNameToHist=histNameSig.format(str( int(mass))) histNameToHist=histNameToHist+"injectedToBkg" totHist.SetName(histNameToHist) totHist.SetTitle(histNameToHist) if totHist is not None and args.debug: print '\n tot events: ', totHist.GetEntries() print ' tot effective events: ', totHist.GetEffectiveEntries() print ' tot sum of weights: ', totHist.GetSumOfWeights() #------------------------------------------ #write to output file outFile.cd() dataLikeSigHist.Write() totHist.Write() #------------------------------------------ #plot if args.plot: QCDHist.SetMarkerStyle(24) totHist.SetMarkerStyle(20) effEntSigHist.SetMarkerStyle(20) effEntSigHist.SetMarkerColor(ROOT.kGreen+1) effEntSigHist.SetLineColor(ROOT.kGreen+1) sigHist.SetMarkerStyle(25) sigHist.SetMarkerColor(ROOT.kAzure+1) sigHist.SetLineColor(ROOT.kAzure+1) scaledSigHist.SetMarkerStyle(26) scaledSigHist.SetMarkerColor(ROOT.kOrange+1) scaledSigHist.SetLineColor(ROOT.kOrange+1) dataLikeSigHist.SetMarkerStyle(24) dataLikeSigHist.SetMarkerColor(ROOT.kRed+1) dataLikeSigHist.SetLineColor(ROOT.kRed+1) smoothSigHist.SetMarkerStyle(32) smoothSigHist.SetMarkerColor(ROOT.kMagenta+1) smoothSigHist.SetLineColor(ROOT.kMagenta+1) hs = ROOT.THStack('hs','hs') hs.Add(QCDHist) hs.Add(totHist) hs.Add(effEntSigHist) hs.Add(sigHist) hs.Add(scaledSigHist) hs.Add(dataLikeSigHist) hs.Add(smoothSigHist) hs.Draw('nostack') hs.GetXaxis().SetTitle(axisLabel) hs.GetXaxis().SetTitleFont(43) hs.GetXaxis().SetTitleSize(textSize) #hs.GetXaxis().SetTitleOffset(1.5) hs.GetXaxis().SetLabelFont(43) hs.GetXaxis().SetLabelSize(textSize) hs.GetYaxis().SetTitle('entries') hs.GetYaxis().SetTitleFont(43) hs.GetYaxis().SetTitleSize(textSize) #hs.GetYaxis().SetTitleOffset(1.5) hs.GetYaxis().SetLabelFont(43) hs.GetYaxis().SetLabelSize(textSize) #------------------------------------------ #labels and legends ax = 0.65 ay = 0.88 #0.85 a = plotTools.getATLAS() p = plotTools.getInternal() n = plotTools.getNote(textSize) l = plotTools.getLegend(ax,ay,textSize) #ATLAS internal a.DrawLatex(ax,ay,'ATLAS') p.DrawLatex(ax+0.13,ay,'internal') #notes notes=[] notes.append('#sqrt{s} = 13 TeV') if float(args.lumi) < -0.1: notes.append('L_{int} = %.0f pb^{-1}'%float(args.lumi)*1e3) else: notes.append('L_{int} = %.1f fb^{-1}'%float(args.lumi)) if modelLabel != '': notes.append('m_{%s} = %0.f GeV'%(modelLabel,float(mass))) else: notes.append('m_{%s} = %0.f GeV'%(model,float(mass))) #notes.append('%s par. fit func.'%nPar) notes+=configNotes for ii, note in enumerate(notes): n.DrawLatex(ax,ay-0.04*(ii+1),note) #legend l.Clear() l.SetTextSize(textSize) l.AddEntry(QCDHist,"QCD background","pl") l.AddEntry(totHist,"signal plus backgournd","pl") l.AddEntry(sigHist,"non-scaled signal","pl") l.AddEntry(scaledSigHist,"scaled signal","pl") l.AddEntry(effEntSigHist,"effective signal","pl") l.AddEntry(dataLikeSigHist,"data-like signal","pl") l.AddEntry(smoothSigHist,"smooth signal","pl") l.SetX1(ax) l.SetY1(ay - 0.04*(len(notes)+1) - 0.04*l.GetNRows()) l.SetX2(ax+0.15) l.SetY2(ay - 0.04*(len(notes)+1)) l.Draw() c1.Update() if args.wait: c1.WaitPrimitive() c1.SaveAs('../figures/signalplusbackground.'+model+'.'+mass+'.GeV.'+slumi+'.ifb.'+histNameSig+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.pdf') outFile.Write() outFile.Close()
def injectDataLikeSignal(args): #---Get dir of the script localdir = os.path.dirname(os.path.realpath(__file__)) #---setting the correct error for MC ROOT.TH1.SetDefaultSumw2() ROOT.TH1.StatOverflows() ROOT.TH2.SetDefaultSumw2() ROOT.TH2.StatOverflows() #---Opening json file try: json_data = open(args.config) config = json.load(json_data) except: print "Cannot open json config file: ", args.config print "---Aborting---" raise RuntimeError #---debug if args.debug: printConfig(config) #--Test if RootFiles exist #bkg doesRootFileExist(localdir + "/" + config["QCDFileDir"] + config["QCDFile"]) #signal signalFileList = makeSignalFileList(config) if args.debug: print("the signal file list being injected is ", signalFileList) for signalFile in signalFileList: doesRootFileExist(signalFile) #TODO test if signal inputfile exist #create outputFile outFileName = makeOutputFileName(config, args) outFile = r.TFile(outFileName, "RECREATE") #---debug if args.debug: print("output file name : ", outFile) #---Get bkg histogram and writing it # skip if bkg histogram already exist bkgFile = ROOT.TFile( "/lustre/SCRATCH/atlas/ywng/WorkSpace/r21/r21SwiftNew/SensitivityStudies/source/scripts//../input_dijetISR2018/bkg//Fluctuated_SwiftFittrijet_HLT_j380_inclusiveAprRewdo.root", 'READ') bkgHist = bkgFile.Get("basicBkgFrom4ParamFit_fluctuated").Clone() #bkgFile = ROOT.TFile(localdir+"/"+config["QCDFileDir"]+"/"+config["QCDFile"], 'READ') #print(bkgFile) #print(localdir+"/"+config["QCDFileDir"]+"/"+config["QCDFile"]) #print(config["histBaseNameBkg"]) #bkgHist = bkgFile.Get(config["histBaseNameBkg"]).Clone() bkgHist.SetTitle(config["histBaseNameBkg"] + "_QCD") outFile.cd() bkgHist.Write() histNameFromInput = config["histBasedNameSig"].format("") sigHist = {} for signalFile in signalFileList: mass = sensitivityTools.getSignalMass(signalFile) sigFile = ROOT.TFile(signalFile) print(sigFile) # getting the original size histogram print("chekc5 in loop") histNameSigUpdated = config["histBasedNameSig"].format(str(mass)) histNameSigUpdated = histNameSigUpdated.encode("ascii") sigHist["ori"] = sigFile.Get(histNameSigUpdated) print(sigHist) sigHist["ori"].SetName(histNameSigUpdated + "_sig") sigHist["ori"].SetTitle(histNameSigUpdated + "_sig") # Scaling the signal histograms up sigHist["scaled"] = sigHist["ori"].Clone() # the scaling is actually a bit off.... sigHist["scaled"].Scale(args.sigScale / sigHist["scaled"].Integral()) sigHist["eff"] = plotTools.getEffectiveEntriesHistogram( sigHist["ori"], config["histBasedNameSig"].format("") + '_eff') #fluctuating the scaled histogram sigHist["dataLike"] = plotTools.getDataLikeHistYvonneVersion( sigHist["eff"], sigHist["scaled"], histNameSigUpdated + "_sig", 1, config["thresholdMass"]) # I am skippig the smoothing part totHist = bkgHist.Clone() totHist.Add(sigHist["dataLike"]) histNameToHist = histNameSigUpdated + "injectedToBkg" totHist.SetName(histNameToHist) totHist.SetTitle(histNameToHist) if args.debug: print("background hist entries: ", bkgHist.Integral()) print("scale: ", args.sigScale) print("signalHistEntries: ", sigHist["dataLike"].Integral()) print("total his entries: ", totHist.Integral()) outFile.cd() totHist.Write() if args.plot: totHist.SetLineColor(r.kGreen) scaledSigHist = sigHist["dataLike"].Clone() scaledSigHist.Scale(totHist.Integral() / sigHist["dataLike"].Integral()) scaledSigHist.SetLineColor(r.kRed) c1 = r.TCanvas(1) c1.SetLogy() bkgHist.Draw() scaledSigHist.Draw("same") totHist.Draw("same") l = plotTools.getLegend(0.65, 0.85, 2) l.AddEntry(bkgHist, "QCDBkgnd", "l") l.AddEntry(scaledSigHist, "signal scaled up", "l") l.AddEntry(totHist, "total", "l") l.Draw() c1.SaveAs("../figures/step02Result." + model + "." + mass + "." + args.sigScale + ".pdf") outFile.Write() outFile.Close()
def doSensitivityScan(args): spFileDir = "/lustre/SCRATCH/atlas/ywng/WorkSpace/r21/r21SwiftNew/SensitivityStudies/source/scripts/../results2/searchphase/" print("# of justabove files afte before eveyrhing : ", countFilesInDirWithKeyword(spFileDir, "JUSTABOVE")) print '\n******************************************' print '\n******************************************' print '\n******************************************' print '\n******************************************' print 'sensitivity scan starting' #------------------------------------------ #input parameters print '\ninput parameters:' argsdict = vars(args) for ii in xrange(len(argsdict)): print ' %s = %s' % ( argsdict.keys()[ii], argsdict.values()[ii], ) #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #get settings print '\nconfig settings:' settings = ROOT.TEnv() if settings.ReadFile(args.configFileName, ROOT.EEnvLevel(0)) != 0: raise SystemExit( '***ERROR*** could not find sensitivity scan config file: %s' % args.configFileName) model = settings.GetValue('signalModel', '') print ' signal model = %s' % model modelLabel = settings.GetValue('signalModelLabel', '').replace('"', '') print ' signal model label = %s' % modelLabel massValuesConfig = settings.GetValue('signalMasses', '2000,3000,4000').split(',') massValuesConfig = [float(m) for m in massValuesConfig] print ' signal masses [GeV] = %s' % massValuesConfig lumiMin = float(settings.GetValue('luminosityMin', '0.1')) #if lumiMin < 0.1: #fb^-1 # lumiMin = 0.1 #fb^-1 print ' minimum luminosity = %s' % lumiMin lumiMax = float(settings.GetValue('luminosityMax', '10.')) print ' maximum luminosity = %s' % lumiMax if lumiMax > 10000.: #fb^-1 lumiMax = 10000. #fb^-1 #QCDFileName = settings.GetValue('QCDFile','../inputs/QCD/histograms.mc.dijet.1p0.ifb.root') #Yvonne edit for dijetISR QCDFileName = settings.GetValue( 'QCDFile', '../inputs/QCD/histograms.mc.QCD.1p0.ifb.root') print ' QCD input file = %s' % QCDFileName histBaseName = settings.GetValue('histBaseName', 'mjj') print ' hist base name = %s' % histBaseName bTaggingWP = settings.GetValue('bTaggingWP', '') #fix_8585 print ' b-tagging WP = %s' % bTaggingWP axisLabel = settings.GetValue('axisLabel', 'm [GeV]') print ' hist x-axis label = %s' % axisLabel nPar = int(settings.GetValue('nFitParameters', '3')) print ' n fit parameters = %s' % nPar nPseudoExps_withSig = settings.GetValue('nPseudoExperimentsWithSig', '1') print ' number of pseudo-experiments = %s' % nPseudoExps_withSig nPseudoExps_bkg = settings.GetValue('nPseudoExperiments_bkg', '1000') print ' number of pseudo-experiments = %s' % nPseudoExps_bkg thresholdMass = float(settings.GetValue('thresholdMass', '1100.')) print ' threshold mass = %s' % thresholdMass seed = float(settings.GetValue('randomSeed', '0')) print ' random seed = %s' % seed notes = settings.GetValue('notes', '').split(',') print ' notes = %s' % notes #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #set variables histName = histBaseName if bTaggingWP != '': histName += '_' + bTaggingWP if args.debug: print '\nhist name = %s' % histName #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #check input file if not os.path.isfile(QCDFileName): raise SystemExit('\n***ERROR*** couldn\'t find QCD file: %s' % QCDFileName) #------------------------------------------ #for windowWidth in [13, 12, 10, 9, 8]:#add 9 later #for windowWidth in [12, 10, 8, 7, 6]:#add 9 later for windowWidth in [12]: #add 9 later print '\n******************************************' print "***************** Window Width " + str( windowWidth) + " ********************" #get list of available mass points massValuesAvailable = [] fileList = os.listdir(localdir + '/../inputs/' + model + '/') print "mass directory: ", localdir + '/../inputs/' + model + '/' for sigFileName in sorted(fileList): if not '.root' in sigFileName: continue massValuesAvailable.append( float(sensitivityTools.getSignalMass(sigFileName))) massValuesAvailable.sort(key=float) #massValues = [m for m in massValues if m >= 10000.0] #DEBUG #massValues = [3000.0] #DEBUG #print '\navailable mass values [GeV]: %s'%massValuesAvailable massValues = list(set(massValuesConfig) & set(massValuesAvailable)) massValues.sort(key=float) massValues.reverse() print 'using mass values [GeV]: %s' % massValues #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #initial luminosity value #lumi = lumiMin #------------------------------------------ #arrays for sensitivity scan graphs gmass = np.array(massValues) glumi = np.zeros_like(gmass) lumiSteps = [0.0, 0.1, 0.2, 0.3, 0.5, 0.7] + range(1, 10) + range( 10, 20, 1) + range(20, 30, 2) + range(30, 50, 3) + range( 50, 100, 5) + range(100, 200, 10) + range(200, 1000, 50) #lumiSteps = [0.1] print "lumiSteps", lumiSteps #reset lumi to lowest value lumiStep = 1 lumiIncrement = 1. #------------------------------------------ #loop over mass values for mass in massValues: #and lumi <= lumiMax: print '\n******************************************' print '\n******************************************' setInitialLumi = False #doing 1000/fb doesn't make much sense, may as well give up? #Yvonne:^^ HUHHH?? #while lumi<(lumiSteps[-1]) : for lumi in lumiSteps: ##add algorithm here... #check it makes sense to run this mass/lumi combination #####TLA2016 thresholds: don't test if above a given lumi as too high #ww9 #mass = [ 1850. 1750. 1050. 750. 650.] #lumi = [ 6.2942564 6.2942564 14.95725 45. 0. ] #ww11 #mass = [ 1850. 1750. 1050. 750. 650.] #lumi = [ 5.46587075 5.46587075 0. 0. 0. ] #just hardwire because i'm so tired #Yvonne: ^^LOL # if mass == 650 and windowWidth == 9 and setInitialLumi==False: # lumi = 74 #136 for 7* # setInitialLumi = True # elif mass == 650 and windowWidth == 10 and setInitialLumi==False: # lumi = 72 # setInitialLumi = True # elif mass == 650 and windowWidth == 11 and setInitialLumi==False: # lumi = 70 # setInitialLumi = True # elif mass == 650 and windowWidth == 12 and setInitialLumi==False: # lumi = 55 # setInitialLumi = True # if mass == 750 and windowWidth == 9 and setInitialLumi==False: # lumi = 35 # setInitialLumi = True # elif mass == 750 and windowWidth == 10 and setInitialLumi==False: # lumi = 30 # setInitialLumi = True # elif mass == 750 and windowWidth == 11 and setInitialLumi==False: # lumi = 26 # setInitialLumi = True # elif mass == 750 and windowWidth == 12 and setInitialLumi==False: # lumi = 15 # setInitialLumi = True # if mass == 1050 and windowWidth == 9 and setInitialLumi==False: # lumi = 13 # setInitialLumi = True # elif mass == 1050 and windowWidth == 10 and setInitialLumi==False: # lumi = 12 # setInitialLumi = True # elif mass == 1050 and windowWidth == 11 and setInitialLumi==False: # lumi = 11 # setInitialLumi = True # elif mass == 1050 and windowWidth == 12 and setInitialLumi==False: # lumi = 10 # setInitialLumi = True # if mass == 1450 and windowWidth == 9 and setInitialLumi==False: # lumi = 5 # setInitialLumi = True # elif mass == 1450 and windowWidth == 10 and setInitialLumi==False: # lumi = 4 # setInitialLumi = True # elif mass == 1450 and windowWidth == 11 and setInitialLumi==False: # lumi = 3 # setInitialLumi = True # elif mass == 1450 and windowWidth == 12 and setInitialLumi==False: # lumi = 2 # setInitialLumi = True # if mass == 1850 and windowWidth == 9 and setInitialLumi==False: # lumi = 5 # lumiIncrement = 1 # setInitialLumi = True # elif mass == 1850 and windowWidth == 10 and setInitialLumi==False: # lumi = 4 # lumiIncrement = 1 # setInitialLumi = True # elif mass == 1850 and windowWidth == 11 and setInitialLumi==False: # lumi = 3 # lumiIncrement = 1 # setInitialLumi = True # elif mass == 1850 and windowWidth == 12 and setInitialLumi==False: # lumi = 2 # lumiIncrement = 1 # setInitialLumi = True #------------------------------------------ #print '\n\n******************************************' #print '******************************************' #print 'testing:' #print 'luminosity = %s ^fb-1'%lumi #print 'mass values [GeV]: %s'%massValues #print '\Testing mass:', mass #print '******************************************' #print '******************************************\n' #luminosity string slumi = ('%.1f' % float(str(lumi).replace('p', '.'))).replace( '.', 'p') print "what's the lumi", lumi #------------------------------------------ #STEP 01 - get data-like QCD for the given luminosity #os.system('python -u step01.getDataLikeQCD.py --config %s --lumi %.1f --tag %s --patch --plot --batch --debug -b'%(args.configFileName, lumi, args.tag)) #HANNO: Commented out to skip #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #STEP 02 - inject signal (fast, do it anyway) #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/datalikeQCD.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' #HANNO: Fixed Lumi in line below!!! debugString = "" if args.debug: debugString = "--debug" #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/NLO_yStar_06_29p7ifb_forSig.root' #HANNO: FIXED NAME #yvonne hack dataLikeQCDFileName = localdir + '/Fluctuated_SwiftFittrijet_HLT_j380_inclusive.root' #HANNO: FIXED NAME os.system( 'python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b %s' % (args.configFileName, dataLikeQCDFileName, lumi, args.tag, debugString)) print( 'python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b --debug' % (args.configFileName, dataLikeQCDFileName, lumi, args.tag)) #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #signal mass print '\n******************************************' print 'Running SearchPhase' print '\n%s mass = %s GeV' % (model, mass) print 'lumi = %s fb^-1' % lumi print 'WindowWidth for SWiFt = %s' % windowWidth print '******************************************' #print("# of justabove files afte before eveyrhing : ", countFilesInDirWithKeyword(spFileDir, "JUSTABOVE")) #------------------------------------------ #step 03 - search fordijet mass resonances (slow, only do it if needed) #signalPlusBackgroundFileName = localdir+'/../results2/signalplusbackground/signalplusbackground.'+model+'.'+slumi+'.ifb.'+"mjj_Gauss_sig__smooth"+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' signalPlusBackgroundFileName = signalPlusBkgFileName( localdir, model, slumi, nPar, seed, tag=args.tag, signalName="mjj_Gauss_sig__smooth") print("YvonnesignalPlusBkgFileName: ", signalPlusBackgroundFileName) #signalPlusBackgroundFileName = localdir+'/../results/signalplusbackground/signalplusbackground.'+model+'.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' if lumi == 0.0: nPseudoExps = nPseudoExps_bkg else: nPseudoExps = nPseudoExps_withSig os.system( 'python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --functionParam %s --nPseudoExps %s --tag %s --batch -b --debug' % (args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, nPar, nPseudoExps, args.tag)) #Hanno: Removed --plot for now print( 'python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --functionParam %s --nPseudoExps %s --tag %s --batch -b --debug' % (args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, nPar, nPseudoExps, args.tag) ) #Hanno: Removed --plot for now #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #check SearchPhase results #this needs to be the same name as the file we made in the search phase - leave the 4param junk in for now #searchphase.Gauss_width15.620.GeV.500p0.ifb.mjj_Gauss.4.par.102.seed.NLO2015_29p7_sensitivityScan_ww13_case5Param ## these are commented out by yvonne #spfilename = localdir+'/../results/searchphase/searchphase.'+model+'.%i'%int(mass)+'.gev.'+slumi+'.ifb.'+histname+'.%i'%npar+'.par.%i'%seed+'.seed.'+args.tag+'_ww'+str(windowwidth)+'.root' #I believe this doesn't depend on mass spFileName = searchPhaseResultName(localdir, model, mass, slumi, histName, nPar, seed, args.tag, windowWidth) if not os.path.isfile(spFileName): raise SystemExit( '\n***ERROR*** couldn\'t find SearchPhase output file for %s mass %s GeV: %s' % (model, int(mass), spFileName)) spFile = ROOT.TFile(spFileName, 'READ') spSignificance = spFile.Get( 'residualHist' ) #this is not quite the significance graph but it works the same for bin edges spSignificance.SetAxisRange( spSignificance.GetBinLowEdge( spSignificance.FindBin(2000.)), 2e4, "X") #------------------------------------------ #fill sensitivity scan graph and remove discovered signal mass values from the list bumpHunterStatOfFitToData = None try: bumpHunterStatOfFitToData = spFile.Get( "bumpHunterStatOfFitToData") except: print "FIT FAILED!!! Try previous lumi with more pseudoexperiments" nPseudoExps = nPseudoExps + 100 lumi = lumi - 1 continue bumpHunterStatValue = bumpHunterStatOfFitToData[0] bumpHunterPValue = bumpHunterStatOfFitToData[1] bumpHunterPValueErr = bumpHunterStatOfFitToData[2] bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh') #bumpHunterStatValue = bumpHunterPLowHigh[0] bumpLowEdge = bumpHunterPLowHigh[1] bumpHighEdge = bumpHunterPLowHigh[2] excludeWindowVector = spFile.Get('excludeWindowNums') excludedWindow = excludeWindowVector[0] excludedWindowLow = excludeWindowVector[1] excludedWindowHigh = excludeWindowVector[2] print '\n******************************************' print 'SearchPhase results summary' print '\n%s mass = %s GeV' % (model, mass) print 'lumi = %s fb^-1' % lumi print "bump range: %s GeV - %s GeV" % (bumpLowEdge, bumpHighEdge) print "BumpHunter stat = %s" % bumpHunterStatValue print "BumpHunter p-value = %s +/- %s" % (bumpHunterPValue, bumpHunterPValueErr) print "excluded window (1=yes, 0=no): ", excludedWindow print "window low edge = %s" % excludedWindowLow print "window high edge = %s" % excludedWindowHigh bumpHunterSigmas = ROOT.Math.normal_quantile( 1. - bumpHunterPValue, 1.) print "BumpHunter sigmas = %s" % bumpHunterSigmas #--------removing old labelled files spFileDir = findDirFromFilePath(spFileName) print("spFileDir in code: ", spFileDir) #spFileDir="/lustre/SCRATCH/atlas/ywng/WorkSpace/r21/r21SwiftNew/SensitivityStudies/source/scripts/../results2/searchphase/" #print("spFileDir hardCoded: ", spFileDir) print("mass", mass) print("windowWidth", windowWidth) removeOldLabelledFile(spFileDir, "JUSTABOVE", mass, windowWidth) removeOldLabelledFile(spFileDir, "JUSTBELOW", mass, windowWidth) removeOldLabelledFile(spFileDir, "NOSIGNAL", mass, windowWidth) print("# of justabove files afte remove: ", countFilesInDirWithKeyword(spFileDir, "JUSTABOVE")) if bumpHunterPValue < 0.01 and int(excludedWindow) > 0: massIndex = np.where(gmass == mass) glumi[massIndex] = lumi print '******************************************' #removeMassValues.append(mass) print "Discovery, with window removal" print "just above" print "SPFile: ", spFileName print "does GPFile exist: ", os.path.isfile(spFileName) #---finding the justabove file justAboveFN = justAboveFileName(spFileName) print("justAboveFileName: ", justAboveFN) os.rename(spFileName, justAboveFN) #setting the SP fileName previous to be one lumi step below exclusion window kicks in #---finding the justbelow file justBelowFN = justBelowFileName(spFileNamePrevious) os.rename(spFileNamePrevious, justBelowFN) print("justBelowFileName: ", justBelowFN) #---finding the nosignal file zeroLumiFN = zeroLumiFileName(spFileName) noSignalFN = noSignalFileName(zeroLumiFN) print("no signal file name: ", noSignalFN) os.rename(zeroLumiFN, noSignalFN) print("# of justabove files:(after setting names) ", countFilesInDirWithKeyword(spFileDir, "JUSTABOVE")) break # get out of the lumi loop, go to next mass point #else :#increment lumi elif bumpHunterPValue < 0.01 and int(excludedWindow) == 0: print '******************************************' print "Discovery, without window removal - increment lumi" lumi = lumi + lumiIncrement else: if lumi * bumpHunterPValue > 1: lumi = ( lumi + 2 * lumi * bumpHunterPValue ) #not even close, take five lumi steps, was 0.5 before print "Not too close. try next time with lumi: ", lumi else: lumi = lumi + lumiIncrement print "Close enough. try next time with lumi: ", lumi #setting a lumi file that is one step lower spFileNamePrevious = spFileName #------------------------------------------ #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #print sensitivity scan results print '\n******************************************' print 'sensitivity scan results' print '******************************************\n' print 'mass = %s' % gmass print 'lumi = %s' % glumi print("# of justabove files close to end: ", countFilesInDirWithKeyword(spFileDir, "JUSTABOVE"))
def doSensitivityScan(args): print '\n******************************************' print 'sensitivity scan' #------------------------------------------ #input parameters print '\ninput parameters:' argsdict = vars(args) for ii in xrange(len(argsdict)): print ' %s = %s' % ( argsdict.keys()[ii], argsdict.values()[ii], ) #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #get settings print '\nconfig settings:' settings = ROOT.TEnv() if settings.ReadFile(args.configFileName, ROOT.EEnvLevel(0)) != 0: raise SystemExit( '***ERROR*** could not find sensitivity scan config file: %s' % args.configFileName) model = settings.GetValue('signalModel', '') print ' signal model = %s' % model modelLabel = settings.GetValue('signalModelLabel', '').replace('"', '') print ' signal model label = %s' % modelLabel massValuesConfig = settings.GetValue('signalMasses', '2000,3000,4000').split(',') massValuesConfig = [float(m) for m in massValuesConfig] print ' signal masses [GeV] = %s' % massValuesConfig lumiMin = float(settings.GetValue('luminosityMin', '0.1')) if lumiMin < 0.1: #fb^-1 lumiMin = 0.1 #fb^-1 print ' minimum luminosity = %s' % lumiMin lumiMax = float(settings.GetValue('luminosityMax', '10.')) print ' maximum luminosity = %s' % lumiMax if lumiMax > 1000.: #fb^-1 lumiMax = 1000. #fb^-1 QCDFileName = settings.GetValue( 'QCDFile', '../inputs/QCD/histograms.mc.dijet.1p0.ifb.root') print ' QCD input file = %s' % QCDFileName histBaseName = settings.GetValue('histBaseName', 'mjj') print ' hist base name = %s' % histBaseName bTaggingWP = settings.GetValue('bTaggingWP', '') #fix_8585 print ' b-tagging WP = %s' % bTaggingWP axisLabel = settings.GetValue('axisLabel', 'm [GeV]') print ' hist x-axis label = %s' % axisLabel nPar = int(settings.GetValue('nFitParameters', '3')) print ' n fit parameters = %s' % nPar nPseudoExps = settings.GetValue('nPseudoExperiments', '1000') print ' number of pseudo-experiments = %s' % nPseudoExps thresholdMass = float(settings.GetValue('thresholdMass', '1100.')) print ' threshold mass = %s' % thresholdMass seed = float(settings.GetValue('randomSeed', '0')) print ' random seed = %s' % seed notes = settings.GetValue('notes', '').split(',') print ' notes = %s' % notes #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #set variables histName = histBaseName if bTaggingWP != '': histName += '_' + bTaggingWP if args.debug: print '\nhist name = %s' % histName #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #check input file if not os.path.isfile(QCDFileName): raise SystemExit('\n***ERROR*** couldn\'t find QCD file: %s' % QCDFileName) #------------------------------------------ #get list of available mass points massValuesAvailable = [] fileList = os.listdir(localdir + '/../inputs/' + model + '/') for sigFileName in sorted(fileList): if not '.root' in sigFileName: continue massValuesAvailable.append( float(sensitivityTools.getSignalMass(sigFileName))) massValuesAvailable.sort(key=float) #massValues = [m for m in massValues if m >= 10000.0] #DEBUG #massValues = [3000.0] #DEBUG print '\navailable mass values [GeV]: %s' % massValuesAvailable massValues = list(set(massValuesConfig) & set(massValuesAvailable)) massValues.sort(key=float) print 'using mass values [GeV]: %s' % massValues #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #initial luminosity value lumi = lumiMin #------------------------------------------ #arrays for sensitivity scan graphs gmass = np.array(massValues) glumi = np.zeros_like(gmass) #------------------------------------------ #loop over mass values and luminosity while len(massValues) > 0 and lumi <= lumiMax: #------------------------------------------ print '\n\n******************************************' print '******************************************' print 'luminosity = %s ^fb-1' % lumi print 'mass values [GeV]: %s' % massValues print '******************************************' print '******************************************\n' #luminosity string slumi = ('%.1f' % float(str(lumi).replace('p', '.'))).replace('.', 'p') #------------------------------------------ #STEP 01 - get data-like QCD for the given luminosity #os.system('python -u step01.getDataLikeQCD.py --config %s --lumi %.1f --patch --tag %s --plot'%(args.configFileName, lumi, args.tag)) #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #STEP 02 - inject signal #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/datalikeQCD.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' dataLikeQCDFileName = localdir + '/../results/datalikeQCD/NLO_yStar_06_29p7ifb_forSig.root' os.system( 'python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot' % (args.configFileName, dataLikeQCDFileName, lumi, args.tag)) #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #loop over signal mass values removeMassValues = [] for mass in massValues: #------------------------------------------ #signal mass print '\n******************************************' print 'SearchPhase' print '\n%s mass = %s GeV' % (model, mass) print 'lumi = %s fb^-1' % lumi print '******************************************' #------------------------------------------ #step 03 - search for dijet mass resonances signalPlusBackgroundFileName = localdir + '/../results/signalplusbackground/signalplusbackground.' + model + '.' + slumi + '.ifb.' + histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag + '.root' os.system( 'python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --tag %s --plot' % (args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, args.tag)) #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #check SearchPhase results print '\n******************************************' print 'SearchPhase results summary' print '\n%s mass = %s GeV' % (model, mass) print 'lumi = %s fb^-1' % lumi spFileName = localdir + '/../results/searchphase/searchphase.' + model + '.%i' % int( mass ) + '.GeV.' + slumi + '.ifb.' + histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag + '.root' if not os.path.isfile(spFileName): raise SystemExit( '\n***ERROR*** couldn\'t find SearchPhase output file for %s mass %s GeV: %s' % (model, int(mass), spFileName)) spFile = ROOT.TFile(spFileName, 'READ') spSignificance = spFile.Get('residualHist') spSignificance.SetAxisRange( spSignificance.GetBinLowEdge(spSignificance.FindBin(2000.)), 2e4, "X") #------------------------------------------ #fill sensitivity scan graph and remove discovered signal mass values from the list bumpHunterStatOfFitToData = spFile.Get("bumpHunterStatOfFitToData") bumpHunterStatValue = bumpHunterStatOfFitToData[0] bumpHunterPValue = bumpHunterStatOfFitToData[1] bumpHunterPValueErr = bumpHunterStatOfFitToData[2] bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh') #bumpHunterStatValue = bumpHunterPLowHigh[0] bumpLowEdge = bumpHunterPLowHigh[1] bumpHighEdge = bumpHunterPLowHigh[2] print "bump range: %s GeV - %s GeV" % (bumpLowEdge, bumpHighEdge) print "BumpHunter stat = %s" % bumpHunterStatValue print "BumpHunter p-value = %s +/- %s" % (bumpHunterPValue, bumpHunterPValueErr) bumpHunterSigmas = ROOT.Math.normal_quantile( 1. - bumpHunterPValue, 1.) print "BumpHunter sigmas = %s" % bumpHunterSigmas if bumpHunterSigmas > 5.: massIndex = np.where(gmass == mass) glumi[massIndex] = lumi removeMassValues.append(mass) print '******************************************' #------------------------------------------ #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #remove mass points discovered for removeMass in removeMassValues: massValues.remove(removeMass) print '\n******************************************' print 'available mass values [GeV]: %s' % massValues print '******************************************' #------------------------------------------ #increase luminosity lumiSteps = [ 0.1, 0.2, 0.3, 0.5, 1.0, 2.0, 3.0, 5.0, 10.0, 20.0, 30.0, 50.0, 100.0, 200.0, 300.0, 500.0, 1000.0 ] #lumiSteps = [0.1, 0.2, 0.5, 1.0, 2.0, 5.0] #SHORT if lumi < lumiSteps[0]: lumi = lumiSteps[0] elif lumi >= lumiSteps[-1]: lumi *= 2. else: for ii in xrange(len(lumiSteps) - 1): if lumi >= lumiSteps[ii] and lumi < lumiSteps[ii + 1]: lumi = lumiSteps[ii + 1] break #------------------------------------------ #print sensitivity scan results print '\n******************************************' print 'sensitivity scan results' print '******************************************\n' print 'mass = %s' % gmass print 'lumi = %s' % glumi
def doSensitivityScan(args): print '\n******************************************' print 'sensitivity scan' #------------------------------------------ #input parameters print '\ninput parameters:' argsdict = vars(args) for ii in xrange(len(argsdict)): print ' %s = %s'%(argsdict.keys()[ii], argsdict.values()[ii],) #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #get settings print '\nconfig settings:' settings = ROOT.TEnv() if settings.ReadFile(args.configFileName,ROOT.EEnvLevel(0)) != 0: raise SystemExit('***ERROR*** could not find sensitivity scan config file: %s'%args.configFileName) model = settings.GetValue('signalModel','') print ' signal model = %s'%model modelLabel = settings.GetValue('signalModelLabel','').replace('"','') print ' signal model label = %s'%modelLabel massValuesConfig = settings.GetValue('signalMasses','2000,3000,4000').split(',') massValuesConfig = [float(m) for m in massValuesConfig] print ' signal masses [GeV] = %s'%massValuesConfig lumiMin = float(settings.GetValue('luminosityMin','0.1')) #if lumiMin < 0.1: #fb^-1 # lumiMin = 0.1 #fb^-1 print ' minimum luminosity = %s'%lumiMin lumiMax = float(settings.GetValue('luminosityMax','10.')) print ' maximum luminosity = %s'%lumiMax if lumiMax > 10000.: #fb^-1 lumiMax = 10000. #fb^-1 QCDFileName = settings.GetValue('QCDFile','../inputs/QCD/histograms.mc.dijet.1p0.ifb.root') print ' QCD input file = %s'%QCDFileName histBaseName = settings.GetValue('histBaseName','mjj') print ' hist base name = %s'%histBaseName bTaggingWP = settings.GetValue('bTaggingWP','') #fix_8585 print ' b-tagging WP = %s'%bTaggingWP axisLabel = settings.GetValue('axisLabel','m [GeV]') print ' hist x-axis label = %s'%axisLabel nPar = int(settings.GetValue('nFitParameters','3')) print ' n fit parameters = %s'%nPar nPseudoExps = settings.GetValue('nPseudoExperiments','1000') print ' number of pseudo-experiments = %s'%nPseudoExps thresholdMass = float(settings.GetValue('thresholdMass','1100.')) print ' threshold mass = %s'%thresholdMass seed = float(settings.GetValue('randomSeed','0')) print ' random seed = %s'%seed notes = settings.GetValue('notes','').split(',') print ' notes = %s'%notes #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #set variables histName = histBaseName if bTaggingWP != '': histName+='_'+bTaggingWP if args.debug: print '\nhist name = %s'%histName #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #check input file if not os.path.isfile(QCDFileName): raise SystemExit('\n***ERROR*** couldn\'t find QCD file: %s'%QCDFileName) #------------------------------------------ for windowWidth in [9]: print "***************** Window Width "+str(windowWidth)+" ********************" #get list of available mass points massValuesAvailable = [] fileList = os.listdir(localdir+'/../inputs/'+model+'/') for sigFileName in sorted(fileList): if not '.root' in sigFileName: continue massValuesAvailable.append( float( sensitivityTools.getSignalMass(sigFileName))) massValuesAvailable.sort(key=float) #massValues = [m for m in massValues if m >= 10000.0] #DEBUG #massValues = [3000.0] #DEBUG print '\navailable mass values [GeV]: %s'%massValuesAvailable massValues = list( set(massValuesConfig) & set(massValuesAvailable) ) massValues.sort(key=float) print 'using mass values [GeV]: %s'%massValues #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #initial luminosity value lumi = lumiMin #------------------------------------------ #arrays for sensitivity scan graphs gmass = np.array(massValues) glumi = np.zeros_like(gmass) lumiSteps = [0.1,0.2,0.3,0.5,0.7]+range(1,10)+range(10,20,1)+range(20,30,2)+range(30,50,3)+range(50,100,5)+range(100,200,10)+range(200,1000,50) #reset lumi to lowest value #------------------------------------------ #loop over mass values for mass in massValues : #and lumi <= lumiMax: lumiStep = 0 previousMassDiscoveryLumi = 0 #doing 1000/fb doesn't make much sense, may as well give up? while lumi<(lumiSteps[-1]) : ##add algorithm here... #check it makes sense to run this mass/lumi combination #####TLA2016 thresholds: don't test if below a given lumi as too low if mass == 550 and lumi < 30 and not lumi == 0.0: continue if mass == 650 and lumi <1 and not lumi == 0.0: continue if mass == 750 and lumi <1 and not lumi == 0.0: continue if mass == 850 and lumi<1 and not lumi == 0.0: continue if mass == 950 and lumi<1 and not lumi == 0.0: continue if mass == 1050 and lumi<1 and not lumi == 0.0: continue if mass == 1250 and lumi<0.7 and not lumi == 0.0: continue if mass == 1450 and lumi<2 and not lumi == 0.0: continue if mass == 1650 and lumi<1 and not lumi == 0.0: continue if mass == 1850 and lumi<1 and not lumi == 0.0: continue #------------------------------------------ print '\n\n******************************************' print '******************************************' print 'testing:' print 'luminosity = %s ^fb-1'%lumi print 'mass values [GeV]: %s'%massValues print '******************************************' print '******************************************\n' #luminosity string slumi = ('%.1f'% float( str(lumi).replace('p','.'))).replace('.','p') #------------------------------------------ #STEP 01 - get data-like QCD for the given luminosity #os.system('python -u step01.getDataLikeQCD.py --config %s --lumi %.1f --tag %s --patch --plot --batch --debug -b'%(args.configFileName, lumi, args.tag)) #HANNO: Commented out to skip #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #STEP 02 - inject signal (fast, do it anyway) #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/datalikeQCD.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' #HANNO: Fixed Lumi in line below!!! dataLikeQCDFileName = localdir+'/../results/datalikeQCD/NLO_yStar_06_29p7ifb_forSig.root' #HANNO: FIXED NAME os.system('python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b --debug'%(args.configFileName, dataLikeQCDFileName, lumi, args.tag)) print('python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b --debug'%(args.configFileName, dataLikeQCDFileName, lumi, args.tag)) #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #signal mass print '\n******************************************' print 'Running SearchPhase' print '\n%s mass = %s GeV'%(model, mass) print 'lumi = %s fb^-1'%lumi print 'WindowWidth for SWiFt = %s'%windowWidth print '******************************************' #------------------------------------------ #step 03 - search for dijet mass resonances (slow, only do it if needed) signalPlusBackgroundFileName = localdir+'/../results/signalplusbackground/signalplusbackground.'+model+'.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' os.system('python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --tag %s --batch -b --debug'%(args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, args.tag)) #Hanno: Removed --plot for now print('python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --tag %s --batch -b --debug'%(args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, args.tag)) #Hanno: Removed --plot for now #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #check SearchPhase results print '\n******************************************' print 'SearchPhase results summary' print '\n%s mass = %s GeV'%(model, mass) print 'lumi = %s fb^-1'%lumi spFileName = localdir+'/../results/searchphase/searchphase.'+model+'.%i'%int(mass)+'.GeV.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.window'+str(windowWidth)+'.root' if not os.path.isfile(spFileName): raise SystemExit('\n***ERROR*** couldn\'t find SearchPhase output file for %s mass %s GeV: %s'%(model, int(mass), spFileName)) spFile = ROOT.TFile(spFileName,'READ') spSignificance = spFile.Get('residualHist') spSignificance.SetAxisRange( spSignificance.GetBinLowEdge( spSignificance.FindBin(2000.) ), 2e4, "X") #------------------------------------------ #fill sensitivity scan graph and remove discovered signal mass values from the list bumpHunterStatOfFitToData = spFile.Get("bumpHunterStatOfFitToData") bumpHunterStatValue = bumpHunterStatOfFitToData[0] bumpHunterPValue = bumpHunterStatOfFitToData[1] bumpHunterPValueErr = bumpHunterStatOfFitToData[2] bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh') #bumpHunterStatValue = bumpHunterPLowHigh[0] bumpLowEdge = bumpHunterPLowHigh[1] bumpHighEdge = bumpHunterPLowHigh[2] print "bump range: %s GeV - %s GeV"%(bumpLowEdge,bumpHighEdge) print "BumpHunter stat = %s"%bumpHunterStatValue print "BumpHunter p-value = %s +/- %s"%(bumpHunterPValue, bumpHunterPValueErr) bumpHunterSigmas = ROOT.Math.normal_quantile(1.-bumpHunterPValue, 1.) print "BumpHunter sigmas = %s"%bumpHunterSigmas #if bumpHunterSigmas > 5.: if bumpHunterPValue < 0.01: massIndex = np.where(gmass == mass) glumi[massIndex] = lumi print '******************************************' #removeMassValues.append(mass) break # get out of the lumi loop, go to next mass point else :#increment lumi #elif bumpHunterPValue < 0.05: lumiStep = lumiStep+1 #close enough, take one step in the lumi #elif bumpHunterPValue < 0.1: lumiStep = (lumiStep+1)*2 #sort of close enough, take two step in the lumi #else : lumiStep = (lumiStep+1)*5 #not even close, take five lumi steps #------------------------------------------ #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ #print sensitivity scan results print '\n******************************************' print 'sensitivity scan results' print '******************************************\n' print 'mass = %s'%gmass print 'lumi = %s'%glumi
def doSensitivityScan(args): fout.write('\n******************************************') fout.write('\n******************************************') #------------------------------------------ #input parameters fout.write('\nSetting input parameters:') argsdict = vars(args) for ii in xrange(len(argsdict)): print ' %s = %s' % ( argsdict.keys()[ii], argsdict.values()[ii], ) #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #get settings fout.write('\n config settings:') settings = ROOT.TEnv() if settings.ReadFile(args.configFileName, ROOT.EEnvLevel(0)) != 0: raise SystemExit( '***ERROR*** could not find sensitivity scan config file: %s' % args.configFileName) model = settings.GetValue('signalModel', '') fout.write('\n signal model = %s' % model) modelLabel = settings.GetValue('signalModelLabel', '').replace('"', '') fout.write('\n signal model label = %s' % modelLabel) massValuesConfig = settings.GetValue('signalMasses', '2000,3000,4000').split(',') massValuesConfig = [float(m) for m in massValuesConfig] fout.write('\n signal masses [GeV] = %s' % massValuesConfig) lumiMin = float(settings.GetValue('luminosityMin', '0.1')) #if lumiMin < 0.1: #fb^-1 # lumiMin = 0.1 #fb^-1 fout.write('\n minimum luminosity = %s' % lumiMin) lumiMax = float(settings.GetValue('luminosityMax', '10.')) fout.write('\n maximum luminosity = %s' % lumiMax) if lumiMax > 10000.: #fb^-1 lumiMax = 10000. #fb^-1 QCDFileName = settings.GetValue( 'QCDFile', '../inputs/QCD/histograms.mc.dijet.1p0.ifb.root') fout.write('\n QCD input file = %s' % QCDFileName) histBaseName = settings.GetValue('histBaseName', 'mjj') fout.write('\n hist base name = %s' % histBaseName) bTaggingWP = settings.GetValue('bTaggingWP', '') #fix_8585 fout.write('\n b-tagging WP = %s' % bTaggingWP) axisLabel = settings.GetValue('axisLabel', 'm [GeV]') fout.write('\n hist x-axis label = %s' % axisLabel) nPar = int(settings.GetValue('nFitParameters', '3')) fout.write('\n n fit parameters = %s' % nPar) nPseudoExps = settings.GetValue('nPseudoExperiments', '1000') fout.write('\n number of pseudo-experiments = %s' % nPseudoExps) thresholdMass = float(settings.GetValue('thresholdMass', '1100.')) fout.write('\n threshold mass = %s' % thresholdMass) seed = float(settings.GetValue('randomSeed', '0')) fout.write('\n random seed = %s' % seed) notes = settings.GetValue('notes', '').split(',') fout.write('\n notes = %s' % notes + "\n") #------------------------------------------ #set variables histName = histBaseName if bTaggingWP != '': histName += '_' + bTaggingWP if args.debug: print '\nhist name = %s' % histName #------------------------------------------ #get directory of this script localdir = os.path.dirname(os.path.realpath(__file__)) #------------------------------------------ #check input file if not os.path.isfile(QCDFileName): raise SystemExit('\n***ERROR*** couldn\'t find QCD file: %s' % QCDFileName) fout.write('\nDone setting initial parameters and checking inputs\n') fout.write('******************************************\n') fout.write('******************************************\n') #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ for windowWidth in [9]: #add 9 later fout.write("******* Testing Window Width " + str(windowWidth) + " ******\n") #get list of available mass points massValuesAvailable = [] fileList = os.listdir(localdir + '/../inputs/' + model + '/') for sigFileName in sorted(fileList): if not '.root' in sigFileName: continue massValuesAvailable.append( float(sensitivityTools.getSignalMass(sigFileName))) massValuesAvailable.sort(key=float) #massValues = [m for m in massValues if m >= 10000.0] #DEBUG #massValues = [3000.0] #DEBUG #print '\navailable mass values [GeV]: %s'%massValuesAvailable massValues = list(set(massValuesConfig) & set(massValuesAvailable)) massValues.sort(key=float) massValues.reverse() fout.write('******* Using list of mass values [GeV]: %s' % massValues + "\n") #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #initial luminosity value, coming from config file lumi = lumiMin #------------------------------------------ #arrays for sensitivity scan graphs gmass = np.array(massValues) glumi = np.zeros_like(gmass) #not used now, just upper bound lumiSteps = [0.1, 0.2, 0.3, 0.5, 0.7] + range(1, 10) + range( 10, 20, 1) + range(20, 30, 2) + range(30, 50, 3) + range( 50, 100, 5) + range(100, 200, 10) + range(200, 1000, 50) #reset lumi to lowest value lumiStep = 0 lumiIncrement = 1 #this gets decided mass point by mass point #loop over mass values for mass in massValues: #and lumi <= lumiMax: setInitialLumi = False #print "******* Testing Mass "+str(mass)+" ******" while lumi < (lumiSteps[-1]): if mass == 650 and windowWidth == 9 and setInitialLumi == False: lumi = 60 setInitialLumi = True if mass == 675 and windowWidth == 9 and setInitialLumi == False: lumi = 40 setInitialLumi = True if mass == 700 and windowWidth == 9 and setInitialLumi == False: lumi = 26 setInitialLumi = True if mass == 725 and windowWidth == 9 and setInitialLumi == False: lumi = 20 setInitialLumi = True if mass == 750 and windowWidth == 9 and setInitialLumi == False: lumi = 10 setInitialLumi = True if mass == 1050 and windowWidth == 9 and setInitialLumi == False: lumi = 12 setInitialLumi = True if mass == 1450 and windowWidth == 9 and setInitialLumi == False: lumi = 10 setInitialLumi = True if mass == 1750 and windowWidth == 9 and setInitialLumi == False: lumi = 5 setInitialLumi = True if mass == 1850 and windowWidth == 9 and setInitialLumi == False: lumi = 3 setInitialLumi = True #luminosity string slumi = ('%.1f' % float(str(lumi).replace('p', '.'))).replace( '.', 'p') fout.write("******* Testing Mass, Lumi " + str(mass) + " GeV, " + str(lumi) + "/fb ******\n") #------------------------------------------ #STEP 01 - get data-like QCD for the given luminosity #os.system('python -u step01.getDataLikeQCD.py --config %s --lumi %.1f --tag %s --patch --plot --batch --debug -b'%(args.configFileName, lumi, args.tag)) #HANNO: Commented out to skip #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #------------------------------------------ fout.write('******************************************\n') fout.write('******************************************\n') fout.write('Injecting signal\n') #STEP 02 - inject signal (fast, do it anyway) #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/datalikeQCD.'+slumi+'.ifb.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root' #HANNO: Fixed Lumi in line below!!! debugString = "" if args.debug: debugString = "--debug" #dataLikeQCDFileName = localdir+'/../results/datalikeQCD/NLO_yStar_06_29p7ifb_forSig.root' #HANNO: FIXED NAME dataLikeQCDFileName = localdir + '/../results/datalikeQCD/Pseudodata_from_DSJ100yStar06_TriggerJets_J100_yStar06_mjj_2016binning_TLArange_data_4param_G_upTo4000.29p7.ifb.root' #CD: FIXED NAME #why calling python within python....but not doing so as it would require major rewrite print( 'python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b --debug' % (args.configFileName, dataLikeQCDFileName, lumi, args.tag)) os.system( 'python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b %s' % (args.configFileName, dataLikeQCDFileName, lumi, args.tag, debugString)) #processOutput = "" #try : # processOutput = subprocess.check_output('python -u step02.injectDataLikeSignal.py --config %s --QCDFile %s --lumi %.1f --tag %s --plot --batch -b %s'%(args.configFileName, dataLikeQCDFileName, lumi, args.tag,debugString), shell=True) #except : # print "Signal-injected files existed already!" #print processOutput fout.write('\nDone injecting signal\n') fout.write('******************************************\n') fout.write('******************************************\n') #lumi = lumiSteps[-1] #------------------------------------------ #TEST #raise SystemExit('\n***TEST*** exit') #------------------------------------------ #run search phase for this signal mass fout.write('******************************************\n') fout.write('******************************************\n') fout.write('Running SearchPhase\n') fout.write('\n%s mass = %s GeV' % (model, mass) + '\n') fout.write('lumi = %s fb^-1' % lumi + '\n') fout.write('WindowWidth for SWiFt = %s' % windowWidth + '\n') fout.write('******************************************\n') fout.write('******************************************\n') #------------------------------------------ #step 03 - search for dijet mass resonances (slow, only do it if needed) signalPlusBackgroundFileName = localdir + '/../results/signalplusbackground/signalplusbackground.' + model + '.' + slumi + '.ifb.' + histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag + '.root' print( 'python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --functionParam %s --nPseudoExps %s --tag %s --batch -b --debug' % (args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, nPar, nPseudoExps, args.tag) ) #Hanno: Removed --plot for now #try : # process = subprocess.check_output('python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --functionParam %s --nPseudoExps %s --tag %s --batch -b --debug'%(args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, nPar, nPseudoExps, args.tag), shell=True) #except : # raise SystemExit('\n***Something went wrong with the search phase***') os.system( 'python -u step03.searchPhase.py --config %s --file %s --mass %s --lumi %s --window %s --functionParam %s --nPseudoExps %s --tag %s --batch -b --debug' % (args.configFileName, signalPlusBackgroundFileName, int(mass), lumi, windowWidth, nPar, nPseudoExps, args.tag)) #Hanno: Removed --plot for now #------------------------------------------ #check SearchPhase results #this needs to be the same name as the file we made in the search phase - leave the 4param junk in for now #searchphase.Gauss_width15.620.GeV.500p0.ifb.mjj_Gauss.4.par.102.seed.NLO2015_29p7_sensitivityScan_ww13_case5Param spFileName = localdir + '/../results/searchphase/searchphase.' + model + '.%i' % int( mass ) + '.GeV.' + slumi + '.ifb.' + histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag + '_ww' + str( windowWidth) + '.root' if not os.path.isfile(spFileName): raise SystemExit( '\n***ERROR*** couldn\'t find SearchPhase output file for %s mass %s GeV: %s' % (model, int(mass), spFileName)) spFile = ROOT.TFile(spFileName, 'READ') spSignificance = spFile.Get( 'residualHist' ) #this is not quite the significance graph but it works the same for bin edges spSignificance.SetAxisRange( spSignificance.GetBinLowEdge( spSignificance.FindBin(2000.)), 2e4, "X") #------------------------------------------ #fill sensitivity scan graph and remove discovered signal mass values from the list bumpHunterStatOfFitToData = None try: bumpHunterStatOfFitToData = spFile.Get( "bumpHunterStatOfFitToData") except: print "FIT FAILED!!! Try previous lumi with more pseudoexperiments" nPseudoExps = nPseudoExps + 100 lumi = lumi - 1 continue bumpHunterStatValue = bumpHunterStatOfFitToData[0] bumpHunterPValue = bumpHunterStatOfFitToData[1] bumpHunterPValueErr = bumpHunterStatOfFitToData[2] bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh') #bumpHunterStatValue = bumpHunterPLowHigh[0] bumpLowEdge = bumpHunterPLowHigh[1] bumpHighEdge = bumpHunterPLowHigh[2] excludeWindowVector = spFile.Get('excludeWindowNums') excludedWindow = excludeWindowVector[0] excludedWindowLow = excludeWindowVector[1] excludedWindowHigh = excludeWindowVector[2] fout.write('\n******************************************') fout.write('SearchPhase results summary\n') fout.write('\n%s mass = %s GeV' % (model, mass) + '\n') fout.write('lumi = %s fb^-1' % lumi + '\n') fout.write("bump range: %s GeV - %s GeV" % (bumpLowEdge, bumpHighEdge) + '\n') fout.write("BumpHunter stat = %s" % bumpHunterStatValue + '\n') fout.write("BumpHunter p-value = %s +/- %s" % (bumpHunterPValue, bumpHunterPValueErr) + '\n') fout.write("excluded window (1=yes, 0=no): " + str(excludedWindow) + '\n') fout.write("window low edge = %s" % excludedWindowLow + '\n') fout.write("window high edge = %s" % excludedWindowHigh + '\n') bumpHunterSigmas = ROOT.Math.normal_quantile( 1. - bumpHunterPValue, 1.) fout.write("BumpHunter sigmas = %s" % bumpHunterSigmas + '\n') #if bumpHunterSigmas > 5.: if bumpHunterPValue < 0.01 and int(excludedWindow) > 0: massIndex = np.where(gmass == mass) glumi[massIndex] = lumi fout.write("******************************************" + '\n') #removeMassValues.append(mass) fout.write("Discovery, with window removal" + '\n') break # get out of the lumi loop, go to next mass point #else :#increment lumi elif bumpHunterPValue < 0.01 and int(excludedWindow) == 0: #massIndex = np.where(gmass == mass) #glumi[massIndex] = lumi fout.write("******************************************" + '\n') #removeMassValues.append(mass) fout.write( "Discovery, without window removal - increment lumi" + '\n') lumi = lumi + lumiIncrement else: if lumi * bumpHunterPValue > 1: lumi = ( lumi + 1 * lumi * bumpHunterPValue ) #not even close, take five lumi steps, was 0.5 before fout.write("Not too close. try next time with lumi: " + str(lumi) + '\n') else: lumi = lumi + lumiIncrement fout.write("Close enough. try next time with lumi: " + str(lumi) + '\n') #------------------------------------------ #print sensitivity scan results fout.write('\n******************************************\n') fout.write( 'sensitivity scan results for all points so far, discovery happened at:\n' ) fout.write('******************************************\n') fout.write('mass = %s' % gmass) fout.write('lumi = %s' % glumi)