Example #1
0
def get_limit(channels,
          unblind=False,
          lumi=1.,
          lumi_rel_error=0.,
          POI='SigXsecOverSM'):
    workspace, _ = histfactory.make_workspace('higgs', channels,
        lumi=lumi,
        lumi_rel_error=lumi_rel_error,
        POI=POI,
        #silence=True
        )
    return get_limit_workspace(workspace, unblind=unblind)
Example #2
0
def write_workspaces(path, prefix, year_mass_category_channel,
                     controls=None,
                     silence=False):
    log.info("writing workspaces ...")
    if controls is None:
        controls = []
    if not os.path.exists(path):
        mkdir_p(path)
    for year, mass_category_channel in year_mass_category_channel.items():
        # write workspaces for each year
        for mass, category_channel in mass_category_channel.items():
            if isinstance(controls, dict):
                if isinstance(controls[year], dict):
                    mass_controls = controls[year][mass].values()
                else:
                    mass_controls = controls[year]
            else:
                mass_controls = controls
            channels = []
            # make workspace for each category
            # include the control region in each
            for category, channel in category_channel.items():
                name = "{0}_{1}_{2}_{3}".format(
                    prefix, year % 1000, category, mass)
                log.info("writing {0} ...".format(name))
                # make workspace
                measurement = histfactory.make_measurement(
                    name, [channel] + mass_controls,
                    POI=POI,
                    const_params=CONST_PARAMS)
                workspace = histfactory.make_workspace(measurement, name=name,
                                                       silence=silence)
                with root_open(os.path.join(path, '{0}.root'.format(name)),
                               'recreate') as workspace_file:
                    workspace.Write()
                    # mu=1 for Asimov data
                    #measurement.SetParamValue('SigXsecOverSM', 1)
                    histfactory.write_measurement(measurement,
                        root_file=workspace_file,
                        xml_path=os.path.join(path, name),
                        silence=silence)
                channels.append(channel)
            # make combined workspace
            name = "{0}_{1}_combination_{2}".format(prefix, year % 1000, mass)
            log.info("writing {0} ...".format(name))
            measurement = histfactory.make_measurement(
                name, channels + mass_controls,
                POI=POI,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement, name=name,
                                                   silence=silence)
            with root_open(os.path.join(path, '{0}.root'.format(name)),
                           'recreate') as workspace_file:
                workspace.Write()
                # mu=1 for Asimov data
                #measurement.SetParamValue('SigXsecOverSM', 1)
                histfactory.write_measurement(measurement,
                    root_file=workspace_file,
                    xml_path=os.path.join(path, name),
                    silence=silence)
    # write combined workspaces over all years
    years = year_mass_category_channel.keys()
    if len(years) == 1:
        return
    masses = year_mass_category_channel[years[0]].keys()
    categories = year_mass_category_channel[years[0]][masses[0]].keys()
    for mass in masses:
        if isinstance(controls, dict):
            if isinstance(controls[year], dict):
                mass_controls = [control for year in years
                                 for control in controls[year][mass].values()]
            else:
                mass_controls = [control for year in years
                                 for control in controls[year]]
        else:
            mass_controls = controls
        channels = []
        # make workspace for each category
        # include the control region in each
        # TODO: categories might be different across years
        """
        for category in categories:
            cat_channels = [year_mass_category_channel[year][mass][category]
                            for year in years]
            name = "{0}_full_{1}_{2}".format(
                prefix, category, mass)
            log.info("writing {0} ...".format(name))
            # make workspace
            measurement = histfactory.make_measurement(
                name, cat_channels + mass_controls,
                POI=POI,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement, name=name,
                                                   silence=silence)
            with root_open(os.path.join(path, '{0}.root'.format(name)),
                           'recreate') as workspace_file:
                workspace.Write()
                # mu=1 for Asimov data
                #measurement.SetParamValue('SigXsecOverSM', 1)
                histfactory.write_measurement(measurement,
                    root_file=workspace_file,
                    xml_path=os.path.join(path, name),
                    silence=silence)
            channels.extend(cat_channels)
        """
        channels = [chan for year in years
                    for chan in year_mass_category_channel[year][mass].values()]
        # make combined workspace
        name = "{0}_full_combination_{1}".format(prefix, mass)
        log.info("writing {0} ...".format(name))
        measurement = histfactory.make_measurement(
            name, channels + mass_controls,
            POI=POI,
            const_params=CONST_PARAMS)
        workspace = histfactory.make_workspace(measurement, name=name,
                                               silence=silence)
        with root_open(os.path.join(path, '{0}.root'.format(name)),
                       'recreate') as workspace_file:
            workspace.Write()
            # mu=1 for Asimov data
            #measurement.SetParamValue('SigXsecOverSM', 1)
            histfactory.write_measurement(measurement,
                root_file=workspace_file,
                xml_path=os.path.join(path, name),
                silence=silence)
Example #3
0
def write_workspaces(path, prefix, year_mass_category_channel,
                     controls=None, shapeControls=None,
                     silence=False):
    log.info("writing workspaces ... for {0}".format(str(year_mass_category_channel)))
    if controls is None:
        controls = []
    if shapeControls is None:
        shapeControls = []

    if not os.path.exists(path):
        mkdir_p(path)
    for year, mass_category_channel in year_mass_category_channel.items():
        # write workspaces for each year
        for mass, category_channel in mass_category_channel.items():
            if isinstance(controls, dict):
                log.info("controls are dicks")
                if isinstance(controls[year], dict):
                    log.info("controls by year are dicks")
                    mass_controls = controls[year][mass].values()
                else:
                    log.info("controls years are dicks")
                    mass_controls = controls[year]
            else:
                mass_controls = controls
            if isinstance(shapeControls, dict):
                log.info("shapeControls are dicks")
                if isinstance(shapeControls[year], dict):
                    log.info("shapeControls by year are dicks")
                    shape_controls = shapeControls[year][mass].values()
                else:
                    log.info("shapeControls years are dicks")
                    shape_controls = shapeControls[year]
            else:
                shape_controls = shapeControls

            log.info("comparing {0} with {1}".format(str(mass_controls),str(shape_controls)))
            channels = []
            # make workspace for each category
            # include the control region in each
            nCategories=0
            for category, channel in category_channel.items():
                nCategories+=1
                name = "{0}_{1}_{2}_{3}".format(
                    prefix, year % 1000, category, mass)
                log.info("writing {0} ...".format(name))
                if mass<0.:
                    parity='m'
                else:
                    parity='p'
                newname = "AllSys_cp_{}_0_{:02.0f}_{}".format(parity, abs(mass*100), prefix)

                # print newname
                measurement = histfactory.make_measurement(
                    newname, [channel] + mass_controls + shape_controls,
                    POI=POI,
                    const_params=CONST_PARAMS)
                workspace = histfactory.make_workspace(measurement, name=newname,
                                                       silence=silence)
                with root_open(os.path.join(path, '{0}.root'.format(newname)),
                               'recreate') as workspace_file:
                    workspace.Write()
                    # mu=1 for Asimov data
#                    measurement.SetParamValue('ATLAS_epsilon', 1)
                    histfactory.write_measurement(measurement,
                        root_file=workspace_file,
                        xml_path=os.path.join(path, newname),
                        silence=silence)
                channels.append(channel)            
            log.info("length of channels is {0}".format(str(len(channels))))
Example #4
0
    def fit_norms(self, field, template, category, region=None,
                  max_iter=10, thresh=1e-7):
        """
        Derive the normalizations of Ztt and QCD from a fit of some variable
        """
        if region is None:
            region = self.target_region
        # initialize QCD and Ztautau normalizations to 50/50 of data yield
        data_yield = self.data.events(category, region)[1].value
        ztt_yield = self.ztautau.events(category, region)[1].value
        qcd_yield = self.qcd.events(category, region)[1].value

        qcd_scale = data_yield / (2 * qcd_yield)
        ztt_scale = data_yield / (2 * ztt_yield)
        qcd_scale_error = 0.
        ztt_scale_error = 0.

        qcd_scale_diff = 100.
        ztt_scale_diff = 100.
        it = 0

        while (ztt_scale_diff > thresh or qcd_scale_diff > thresh) and it < max_iter:
            it += 1
            # keep fitting until normalizations converge

            self.qcd.scale = qcd_scale
            self.ztautau.scale = ztt_scale

            channels = self.make_var_channels(
                template, field, [category],
                region, include_signal=False,
                normalize=False)

            # create a workspace
            measurement = histfactory.make_measurement(
                'normalization_{0}'.format(field), channels,
                POI=None,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement, silence=True)

            # fit workspace
            minim = workspace.fit()
            fit_result = minim.save()

            # get fitted norms and errors
            qcd = fit_result.floatParsFinal().find(
                'ATLAS_norm_HH_{0:d}_QCD'.format(self.year))
            ztt = fit_result.floatParsFinal().find(
                'ATLAS_norm_HH_{0:d}_Ztt'.format(self.year))
            qcd_scale_new = qcd.getVal()
            qcd_scale_error = qcd.getError()
            ztt_scale_new = ztt.getVal()
            ztt_scale_error = ztt.getError()

            qcd_scale_diff = abs(qcd_scale_new - 1.)
            ztt_scale_diff = abs(ztt_scale_new - 1.)

            qcd_scale_error *= qcd_scale / qcd_scale_new
            qcd_scale *= qcd_scale_new
            ztt_scale_error *= ztt_scale / ztt_scale_new
            ztt_scale *= ztt_scale_new

        self.qcd.scale = qcd_scale
        self.ztautau.scale = ztt_scale
        self.qcd.scale_error = qcd_scale_error
        self.ztautau.scale_error = ztt_scale_error

        return qcd_scale, qcd_scale_error, ztt_scale, ztt_scale_error
Example #5
0
def write_workspaces(path,
                     prefix,
                     year_mass_category_channel,
                     controls=None,
                     silence=False):
    log.info("writing workspaces ...")
    if controls is None:
        controls = []
    if not os.path.exists(path):
        mkdir_p(path)
    for year, mass_category_channel in year_mass_category_channel.items():
        # write workspaces for each year
        for mass, category_channel in mass_category_channel.items():
            if isinstance(controls, dict):
                if isinstance(controls[year], dict):
                    mass_controls = controls[year][mass].values()
                else:
                    mass_controls = controls[year]
            else:
                mass_controls = controls
            channels = []
            # make workspace for each category
            # include the control region in each
            for category, channel in category_channel.items():
                name = "{0}_{1}_{2}_{3}".format(prefix, year % 1000, category,
                                                mass)
                log.info("writing {0} ...".format(name))
                # make workspace
                measurement = histfactory.make_measurement(
                    name, [channel] + mass_controls,
                    POI=POI,
                    const_params=CONST_PARAMS)
                workspace = histfactory.make_workspace(measurement,
                                                       name=name,
                                                       silence=silence)
                with root_open(os.path.join(path, '{0}.root'.format(name)),
                               'recreate') as workspace_file:
                    workspace.Write()
                    # mu=1 for Asimov data
                    #measurement.SetParamValue('SigXsecOverSM', 1)
                    histfactory.write_measurement(measurement,
                                                  root_file=workspace_file,
                                                  xml_path=os.path.join(
                                                      path, name),
                                                  silence=silence)
                channels.append(channel)
            # make combined workspace
            name = "{0}_{1}_combination_{2}".format(prefix, year % 1000, mass)
            log.info("writing {0} ...".format(name))
            measurement = histfactory.make_measurement(
                name,
                channels + mass_controls,
                POI=POI,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement,
                                                   name=name,
                                                   silence=silence)
            with root_open(os.path.join(path, '{0}.root'.format(name)),
                           'recreate') as workspace_file:
                workspace.Write()
                # mu=1 for Asimov data
                #measurement.SetParamValue('SigXsecOverSM', 1)
                histfactory.write_measurement(measurement,
                                              root_file=workspace_file,
                                              xml_path=os.path.join(
                                                  path, name),
                                              silence=silence)
    # write combined workspaces over all years
    years = year_mass_category_channel.keys()
    if len(years) == 1:
        return
    masses = year_mass_category_channel[years[0]].keys()
    categories = year_mass_category_channel[years[0]][masses[0]].keys()
    for mass in masses:
        if isinstance(controls, dict):
            if isinstance(controls[year], dict):
                mass_controls = [
                    control for year in years
                    for control in controls[year][mass].values()
                ]
            else:
                mass_controls = [
                    control for year in years for control in controls[year]
                ]
        else:
            mass_controls = controls
        channels = []
        # make workspace for each category
        # include the control region in each
        # TODO: categories might be different across years
        """
        for category in categories:
            cat_channels = [year_mass_category_channel[year][mass][category]
                            for year in years]
            name = "{0}_full_{1}_{2}".format(
                prefix, category, mass)
            log.info("writing {0} ...".format(name))
            # make workspace
            measurement = histfactory.make_measurement(
                name, cat_channels + mass_controls,
                POI=POI,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement, name=name,
                                                   silence=silence)
            with root_open(os.path.join(path, '{0}.root'.format(name)),
                           'recreate') as workspace_file:
                workspace.Write()
                # mu=1 for Asimov data
                #measurement.SetParamValue('SigXsecOverSM', 1)
                histfactory.write_measurement(measurement,
                    root_file=workspace_file,
                    xml_path=os.path.join(path, name),
                    silence=silence)
            channels.extend(cat_channels)
        """
        channels = [
            chan for year in years
            for chan in year_mass_category_channel[year][mass].values()
        ]
        # make combined workspace
        name = "{0}_full_combination_{1}".format(prefix, mass)
        log.info("writing {0} ...".format(name))
        measurement = histfactory.make_measurement(name,
                                                   channels + mass_controls,
                                                   POI=POI,
                                                   const_params=CONST_PARAMS)
        workspace = histfactory.make_workspace(measurement,
                                               name=name,
                                               silence=silence)
        with root_open(os.path.join(path, '{0}.root'.format(name)),
                       'recreate') as workspace_file:
            workspace.Write()
            # mu=1 for Asimov data
            #measurement.SetParamValue('SigXsecOverSM', 1)
            histfactory.write_measurement(measurement,
                                          root_file=workspace_file,
                                          xml_path=os.path.join(path, name),
                                          silence=silence)
Example #6
0
    def fit_norms(self, field, template, category, region=None,
                  max_iter=10, thresh=1e-7):
        """
        Derive the normalizations of Ztt and QCD from a fit of some variable
        """
        if region is None:
            region = self.target_region
        # initialize QCD and Ztautau normalizations to 50/50 of data yield
        data_yield = self.data.events(category, region)[1].value
        ztt_yield = self.ztautau.events(category, region)[1].value
        qcd_yield = self.qcd.events(category, region)[1].value

        qcd_scale = data_yield / (2 * qcd_yield)
        ztt_scale = data_yield / (2 * ztt_yield)
        qcd_scale_error = 0.
        ztt_scale_error = 0.

        qcd_scale_diff = 100.
        ztt_scale_diff = 100.
        it = 0

        while (ztt_scale_diff > thresh or qcd_scale_diff > thresh) and it < max_iter:
            it += 1
            # keep fitting until normalizations converge

            self.qcd.scale = qcd_scale
            self.ztautau.scale = ztt_scale

            channels = self.make_var_channels(
                template, field, [category],
                region, include_signal=False,
                normalize=False)

            # create a workspace
            measurement = histfactory.make_measurement(
                'normalization_{0}'.format(field), channels,
                POI=None,
                const_params=CONST_PARAMS)
            workspace = histfactory.make_workspace(measurement, silence=True)

            # fit workspace
            minim = workspace.fit()
            fit_result = minim.save()

            # get fitted norms and errors
            qcd = fit_result.floatParsFinal().find(
                'ATLAS_norm_HH_{0:d}_QCD'.format(self.year))
            ztt = fit_result.floatParsFinal().find(
                'ATLAS_norm_HH_{0:d}_Ztt'.format(self.year))
            qcd_scale_new = qcd.getVal()
            qcd_scale_error = qcd.getError()
            ztt_scale_new = ztt.getVal()
            ztt_scale_error = ztt.getError()

            qcd_scale_diff = abs(qcd_scale_new - 1.)
            ztt_scale_diff = abs(ztt_scale_new - 1.)

            qcd_scale_error *= qcd_scale / qcd_scale_new
            qcd_scale *= qcd_scale_new
            ztt_scale_error *= ztt_scale / ztt_scale_new
            ztt_scale *= ztt_scale_new

        self.qcd.scale = qcd_scale
        self.ztautau.scale = ztt_scale
        self.qcd.scale_error = qcd_scale_error
        self.ztautau.scale_error = ztt_scale_error

        return qcd_scale, qcd_scale_error, ztt_scale, ztt_scale_error