コード例 #1
0
ファイル: HaaLimits.py プロジェクト: gracehaza/CombineLimits
 def buildModel(self,region='PP',**kwargs):
     tag = kwargs.pop('tag',region)
 
     # jpsi
     jpsi1S = Models.Voigtian('jpsi1S',
         mean  = [3.1,2.9,3.2],
         sigma = [0.1,0,1],
         width = [0.1,0.01,1],
     )
     #nameJ1 = 'jpsi1S{}'.format('_'+tag if tag else '')
     nameJ1 = 'jpsi1S'
     jpsi1S.build(self.workspace,nameJ1)
 
     jpsi2S = Models.Gaussian('jpsi2S',
         mean  = [3.7,3.6,3.8],
         sigma = [0.1,0.01,1],
         width = [0.1,0.01,1],
     )
     #nameJ2 = 'jpsi2S{}'.format('_'+tag if tag else '')
     nameJ2 = 'jpsi2S'
     jpsi2S.build(self.workspace,nameJ2)
 
     #jpsi = Models.Sum('jpsi',
     #    **{
     #        nameJ1 : [0.5,0,1] if tag=='PP' else [0.5,0,1],
     #        nameJ2 : [0.6,0,1] if tag=='PP' else [0.2,0,1],
     #        'recursive' : True,
     #    }
     #)
     ##nameJ = 'jpsi{}'.format('_'+tag if tag else '')
     #nameJ= 'jpsi'
     #jpsi.build(self.workspace,nameJ)
 
     # upsilon
     upsilon1S = Models.Gaussian('upsilon1S',
         mean  = [9.5,9.3,9.7],
         sigma = [0.1,0.01,0.3],
     )
     #nameU1 = 'upsilon1S{}'.format('_'+tag if tag else '')
     nameU1 = 'upsilon1S'
     upsilon1S.build(self.workspace,nameU1)
 
     upsilon2S = Models.Gaussian('upsilon2S',
         mean  = [10.0,9.8,10.2],
         sigma = [0.1,0.01,0.3],
     )
     #nameU2 = 'upsilon2S{}'.format('_'+tag if tag else '')
     nameU2 = 'upsilon2S'
     upsilon2S.build(self.workspace,nameU2)
 
     upsilon3S = Models.Gaussian('upsilon3S',
         mean  = [10.3,10.2,10.5],
         sigma = [0.1,0.02,0.3],
     )
     #nameU3 = 'upsilon3S{}'.format('_'+tag if tag else '')
     nameU3 = 'upsilon3S'
     upsilon3S.build(self.workspace,nameU3)
 
     #upsilon = Models.Sum('upsilon',
     #    **{
     #        nameU1 : [0.43,0,1],
     #        nameU2 : [0.20,0,1],
     #        nameU3 : [1,0,1],
     #        'recursive' : True,
     #    }
     #)
     ##nameU = 'upsilon{}'.format('_'+tag if tag else '')
     #nameU= 'upsilon'
     #upsilon.build(self.workspace,nameU)
 
     # continuum background
     cont = Models.Chebychev('cont',
         order = 2,
         p0 = [-1,-1.4,0],
         p1 = [0.25,0,0.5],
         p2 = [0.03,-1,1],
     )
     nameC = 'cont{}'.format('_'+tag if tag else '')
     cont.build(self.workspace,nameC)
 
     cont1 = Models.Exponential('cont1',
         lamb = [-0.20,-1,0],
     )
     nameC1 = 'cont1{}'.format('_'+tag if tag else '')
     cont1.build(self.workspace,nameC1)
 
     cont2 = Models.Exponential('cont2',
         lamb = [-0.05,-1,0],
     )
     nameC2 = 'cont2{}'.format('_'+tag if tag else '')
     cont2.build(self.workspace,nameC2)
 
     cont3 = Models.Exponential('cont3',
         lamb = [-0.75,-5,0],
     )
     nameC3 = 'cont3{}'.format('_'+tag if tag else '')
     cont3.build(self.workspace,nameC3)
 
     cont4 = Models.Exponential('cont4',
         lamb = [-2,-5,0],
     )
     nameC4 = 'cont4{}'.format('_'+tag if tag else '')
     cont4.build(self.workspace,nameC4)
 
     #cont = Models.Sum('cont',
     #    **{
     #        nameC1 : [0.95,0,1],
     #        nameC2 : [0.05,0,1],
     #        'recursive' : True,
     #    }
     #)
     #nameC = 'cont{}'.format('_'+tag if tag else '')
     #cont.build(self.workspace,nameC)
 
     # sum
     if self.XRANGE[0]<4 and self.XRANGE[1]>10:
         # jpsi and upsilon
         bg = Models.Sum('bg',
             **{
                 #nameC : [0.1,0,1],
                 nameC1: [0.2,0,1],
                 nameC2: [0.5,0,1],
                 nameC3: [0.8,0,1],
                 #nameC4: [0.1,0,1],
                 #nameJ : [0.9,0,1],
                 nameJ1: [0.9,0,1],
                 nameJ2: [0.9,0,1],
                 #nameU : [0.1,0,1],
                 nameU1: [0.1,0,1],
                 nameU2: [0.1,0,1],
                 nameU3: [0.1,0,1],
                 'recursive' : True,
             }
         )
     elif self.XRANGE[0]<4:
         # only jpsi
         bg = Models.Sum('bg',
             **{
                 #nameC : [0.1,0,1],
                 nameC3: [0.1,0,1],
                 nameC2: [0.1,0,1],
                 #nameJ : [0.9,0,1],
                 nameJ1: [0.9,0,1],
                 nameJ2: [0.9,0,1],
                 'recursive' : True,
             }
         )
     else:
         # only upsilon
         bg = Models.Sum('bg',
             **{
                 #nameC : [0.1,0,1],
                 nameC1: [0.5,0,1],
                 nameC2: [0.7,0,1],
                 #nameU : [0.5,0,1],
                 nameU1: [0.5,0,1],
                 nameU2: [0.5,0,1],
                 nameU3: [0.5,0,1],
                 'recursive' : True,
             }
         )
     name = 'bg_{}'.format(region)
     bg.build(self.workspace,name)
コード例 #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
コード例 #3
0
ファイル: HaaLimits.py プロジェクト: gracehaza/CombineLimits
 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))
コード例 #4
0
    def buildSpline(self,
                    h,
                    vals,
                    errs,
                    integrals,
                    region='PP',
                    shifts=[],
                    **kwargs):
        '''
        Get the signal spline for a given Higgs mass.
        Required arguments:
            h = higgs mass
            vals = dict with fitted param values
            errs = dict with fitted param errors
            integrals = dict with integrals for given distribution

        The dict should be of the form:
            vals = {
                '' : vals_central,
                'shift0Up': vals_shift0Up,
                'shift0Down': vals_shift0Down,
                ...
            }
        where vals_central, etc ar the fitted values from "fitSignal"
        each shift key to be used should be included in the argument "shifts"
            shifts = [
                'shift0',
                'shift1',
                ...
            ]
        and similarly for errors and integrals.
        '''
        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]

        # create parameter splines
        params = ['mean', 'width', 'sigma']
        splines = {}
        for param in params:
            name = '{param}_h{h}_{region}'.format(param=param,
                                                  h=h,
                                                  region=region)
            paramMasses = avals
            paramValues = [
                vals[''][h][a]['{param}_h{h}_a{a}_{region}'.format(
                    param=param, h=h, a=a, region=region)] for a in amasses
            ]
            paramShifts = {}
            for shift in shifts:
                shiftValuesUp = [
                    vals[shift + 'Up'][h][a][
                        '{param}_h{h}_a{a}_{region}_{shift}Up'.format(
                            param=param, h=h, a=a, region=region, shift=shift)]
                    for a in amasses
                ]
                shiftValuesDown = [
                    vals[shift + 'Down'][h][a][
                        '{param}_h{h}_a{a}_{region}_{shift}Down'.format(
                            param=param, h=h, a=a, region=region, shift=shift)]
                    for a in amasses
                ]
                paramShifts[shift] = {
                    'up': shiftValuesUp,
                    'down': shiftValuesDown
                }
            spline = Models.Spline(
                name,
                masses=paramMasses,
                values=paramValues,
                shifts=paramShifts,
            )
            spline.build(self.workspace, name)
            splines[name] = spline

        # integral spline
        name = 'integral_{}_{}'.format(self.SPLINENAME.format(h=h), region)
        paramMasses = avals
        paramValues = [integrals[''][h][a] for a in amasses]
        paramShifts = {}
        for shift in shifts:
            shiftValuesUp = [integrals[shift + 'Up'][h][a] for a in amasses]
            shiftValuesDown = [
                integrals[shift + 'Down'][h][a] for a in amasses
            ]
            paramShifts[shift] = {'up': shiftValuesUp, 'down': shiftValuesDown}
        spline = Models.Spline(
            name,
            masses=paramMasses,
            values=paramValues,
            shifts=paramShifts,
        )
        spline.build(self.workspace, name)
        splines[name] = spline

        # create model
        if fit:
            print 'Need to reimplement fitting'
            raise
        else:
            model = Models.Voigtian(
                self.SPLINENAME.format(h=h), **{
                    param: '{param}_h{h}_{region}'.format(param=param,
                                                          h=h,
                                                          region=region)
                    for param in params
                })
        model.build(self.workspace, '{}_{}'.format(self.SPLINENAME.format(h=h),
                                                   region))

        return model