Esempio n. 1
0
 def buildSpline(self,h,region='PP',shift=''):
     '''
     Get the signal spline for a given Higgs mass.
     Required arguments:
         h = higgs mass
     '''
     histMap = self.histMap[region][shift]
     tag= '{}{}'.format(region,'_'+shift if shift else '')
     # initial fit
     results = {}
     errors = {}
     results[h] = {}
     errors[h] = {}
     for a in self.AMASSES:
         ws = ROOT.RooWorkspace('sig')
         ws.factory('x[{0}, {1}]'.format(*self.XRANGE))
         ws.var('x').setUnit('GeV')
         ws.var('x').setPlotLabel(self.XLABEL)
         ws.var('x').SetTitle(self.XLABEL)
         model = Models.Voigtian('sig',
             mean  = [a,0,30],
             width = [0.01*a,0,5],
             sigma = [0.01*a,0,5],
         )
         model.build(ws, 'sig')
         hist = histMap[self.SIGNAME.format(h=h,a=a)]
         results[h][a], errors[h][a] = model.fit(ws, hist, 'h{}_a{}_{}'.format(h,a,tag), saveDir=self.plotDir, save=True, doErrors=True)
 
     models = {
         'mean' : Models.Chebychev('mean',  order = 1, p0 = [0,-1,1], p1 = [0.1,-1,1], p2 = [0.03,-1,1]),
         'width': Models.Chebychev('width', order = 1, p0 = [0,-1,1], p1 = [0.1,-1,1], p2 = [0.03,-1,1]),
         'sigma': Models.Chebychev('sigma', order = 1, p0 = [0,-1,1], p1 = [0.1,-1,1], p2 = [0.03,-1,1]),
     }
 
     for param in ['mean', 'width', 'sigma']:
         ws = ROOT.RooWorkspace(param)
         ws.factory('x[{},{}]'.format(*self.XRANGE))
         ws.var('x').setUnit('GeV')
         ws.var('x').setPlotLabel(self.XLABEL)
         ws.var('x').SetTitle(self.XLABEL)
         model = models[param]
         model.build(ws, param)
         name = '{}_{}{}'.format(param,h,tag)
         hist = ROOT.TH1D(name, name, len(self.AMASSES), 4, 22)
         vals = [results[h][a]['{}_h{}_a{}_{}'.format(param,h,a,tag)] for a in self.AMASSES]
         errs = [errors[h][a]['{}_h{}_a{}_{}'.format(param,h,a,tag)] for a in self.AMASSES]
         for i,a in enumerate(self.AMASSES):
             b = hist.FindBin(a)
             hist.SetBinContent(b,vals[i])
             hist.SetBinError(b,errs[i])
         model.fit(ws, hist, name, saveDir=self.plotDir, save=True)
 
     # create model
     for a in self.AMASSES:
         print h, a, results[h][a]
     model = Models.VoigtianSpline(self.SPLINENAME.format(h=h),
         **{
             'masses' : self.AMASSES,
             'means'  : [results[h][a]['mean_h{0}_a{1}_{2}'.format(h,a,tag)] for a in self.AMASSES],
             'widths' : [results[h][a]['width_h{0}_a{1}_{2}'.format(h,a,tag)] for a in self.AMASSES],
             'sigmas' : [results[h][a]['sigma_h{0}_a{1}_{2}'.format(h,a,tag)] for a in self.AMASSES],
         }
     )
     if self.binned:
         integrals = [histMap[self.SIGNAME.format(h=h,a=a)].Integral() for a in self.AMASSES]
     else:
         integrals = [histMap[self.SIGNAME.format(h=h,a=a)].sumEntries('x>{} && x<{}'.format(*self.XRANGE)) for a in self.AMASSES]
     model.setIntegral(self.AMASSES,integrals)
     model.build(self.workspace,'{}_{}'.format(self.SPLINENAME.format(h=h),tag))
     model.buildIntegral(self.workspace,'integral_{}_{}'.format(self.SPLINENAME.format(h=h),tag))
Esempio n. 2
0
    def buildSpline(self,h,region='PP',shift='',**kwargs):
        '''
        Get the signal spline for a given Higgs mass.
        Required arguments:
            h = higgs mass
        '''
        fit = kwargs.get('fit',False)      # will fit the spline parameters rather than a simple spline
        amasses = self.AMASSES
        if h>125: amasses = [a for a in amasses if a not in ['3p6',4,6]]
        avals = [float(str(x).replace('p','.')) for x in amasses]
        histMap = self.histMap[region][shift]
        tag= '{}{}'.format(region,'_'+shift if shift else '')
        # initial fit
        results = {}
        errors = {}
        results[h] = {}
        errors[h] = {}
        for a in amasses:
            aval = float(str(a).replace('p','.'))
            ws = ROOT.RooWorkspace('sig')
            ws.factory('x[{0}, {1}]'.format(*self.XRANGE))
            ws.var('x').setUnit('GeV')
            ws.var('x').setPlotLabel(self.XLABEL)
            ws.var('x').SetTitle(self.XLABEL)
            model = Models.Voigtian('sig',
                mean  = [aval,0,30],
                width = [0.01*aval,0,5],
                sigma = [0.01*aval,0,5],
            )
            model.build(ws, 'sig')
            hist = histMap[self.SIGNAME.format(h=h,a=a)]
            saveDir = '{}/{}'.format(self.plotDir,shift if shift else 'central')
            results[h][a], errors[h][a] = model.fit(ws, hist, 'h{}_a{}_{}'.format(h,a,tag), saveDir=saveDir, save=True, doErrors=True)
    

        # Fit using ROOT rather than RooFit for the splines
        fitFuncs = {
            'mean' : 'pol1',
            'width': 'pol2',
            'sigma': 'pol2',
        }

        xs = []
        x = self.XRANGE[0]
        while x<=self.XRANGE[1]:
            xs += [x]
            x += float(self.XRANGE[1]-self.XRANGE[0])/100
        fittedParams = {}
        for param in ['mean','width','sigma']:
            name = '{}_{}{}'.format(param,h,tag)
            xerrs = [0]*len(amasses)
            vals = [results[h][a]['{}_h{}_a{}_{}'.format(param,h,a,tag)] for a in amasses]
            errs = [errors[h][a]['{}_h{}_a{}_{}'.format(param,h,a,tag)] for a in amasses]
            graph = ROOT.TGraphErrors(len(avals),array('d',avals),array('d',vals),array('d',xerrs),array('d',errs))
            savedir = '{}/{}'.format(self.plotDir,shift if shift else 'central')
            python_mkdir(savedir)
            savename = '{}/{}_Fit'.format(savedir,name)
            canvas = ROOT.TCanvas(savename,savename,800,800)
            graph.Draw()
            graph.SetTitle('')
            graph.GetHistogram().GetXaxis().SetTitle(self.SPLINELABEL)
            graph.GetHistogram().GetYaxis().SetTitle(param)
            if fit:
               fitResult = graph.Fit(fitFuncs[param])
               func = graph.GetFunction(fitFuncs[param])
               fittedParams[param] = [func.Eval(x) for x in xs]
            canvas.Print('{}.png'.format(savename))

    
        # create model
        for a in amasses:
            print h, a, results[h][a]
        if fit:
            model = Models.VoigtianSpline(self.SPLINENAME.format(h=h),
                **{
                    'masses' : xs,
                    'means'  : fittedParams['mean'],
                    'widths' : fittedParams['width'],
                    'sigmas' : fittedParams['sigma'],
                }
            )
        else:
            model = Models.VoigtianSpline(self.SPLINENAME.format(h=h),
                **{
                    'masses' : avals,
                    'means'  : [results[h][a]['mean_h{0}_a{1}_{2}'.format(h,a,tag)] for a in amasses],
                    'widths' : [results[h][a]['width_h{0}_a{1}_{2}'.format(h,a,tag)] for a in amasses],
                    'sigmas' : [results[h][a]['sigma_h{0}_a{1}_{2}'.format(h,a,tag)] for a in amasses],
                }
            )
        if self.binned:
            integrals = [histMap[self.SIGNAME.format(h=h,a=a)].Integral() for a in amasses]
        else:
            integrals = [histMap[self.SIGNAME.format(h=h,a=a)].sumEntries('x>{} && x<{}'.format(*self.XRANGE)) for a in amasses]
        print 'Integrals', tag, h, integrals

        param = 'integral'
        funcname = 'pol2'
        name = '{}_{}{}'.format(param,h,tag)
        vals = integrals
        graph = ROOT.TGraph(len(avals),array('d',avals),array('d',vals))
        savedir = '{}/{}'.format(self.plotDir,shift if shift else 'central')
        python_mkdir(savedir)
        savename = '{}/{}_Fit'.format(savedir,name)
        canvas = ROOT.TCanvas(savename,savename,800,800)
        graph.Draw()
        graph.SetTitle('')
        graph.GetHistogram().GetXaxis().SetTitle(self.SPLINELABEL)
        graph.GetHistogram().GetYaxis().SetTitle('integral')
        if fit:
            fitResult = graph.Fit(funcname)
            func = graph.GetFunction(funcname)
            newintegrals = [func.Eval(x) for x in xs]
            # dont fit integrals
            #model.setIntegral(xs,newintegrals)
        canvas.Print('{}.png'.format(savename))
        model.setIntegral(avals,integrals)

        model.build(self.workspace,'{}_{}'.format(self.SPLINENAME.format(h=h),tag))
        model.buildIntegral(self.workspace,'integral_{}_{}'.format(self.SPLINENAME.format(h=h),tag))

        savedir = '{}/{}'.format(self.fitsDir,shift if shift else 'central')
        python_mkdir(savedir)
        savename = '{}/h{}_{}.json'.format(savedir,h,tag)
        jsonData = {'vals': results, 'errs': errors, 'integrals': {a:integral for a,integral in zip(avals,integrals)}}
        self.dump(savename,jsonData)

        # return the model
        # this can be used to determine if you want to keep this shift
        return model