def create_measurement(com, category, variable, channel, phase_space, norm_method):
    if com == 13:
        # exclude non existing systematics
        if 'VJets' in category and 'scale' in category:
            print('Excluding {0} for now'.format(category))
            return
    config = XSectionConfig(com)
    met_type = get_met_type(category, config)
    should_not_run_systematic = category in config.met_systematics_suffixes and variable in config.variables_no_met and not 'JES' in category and not 'JER' in category
    if should_not_run_systematic:
        # no MET uncertainty on HT (but JES and JER of course)
        return

    m = None
    if category == 'central':
        m = Measurement(category)
    else:
        vjet_systematics = [config.vjets_theory_systematic_prefix +
                            systematic for systematic in config.generator_systematics]
        if category in config.categories_and_prefixes.keys() or \
                category in config.met_systematics_suffixes or \
                category in vjet_systematics:
            m = Systematic(category,
                           stype=Systematic.SHAPE,
                           affected_samples=config.samples)
        elif category in config.rate_changing_systematics_names:
            m = config.rate_changing_systematics_values[category]

        elif category == 'QCD_shape':
            m = Systematic(category,
                           stype=Systematic.SHAPE,
                           affected_samples=['QCD'],
            )

    m.setVariable(variable)
    m.setCentreOfMassEnergy(com)
    m.setChannel(channel)
    m.setMETType(met_type)

    inputs = {
        'channel': config.analysis_types[channel],
        'met_type': met_type,
        'selection': 'Ref selection',
        'btag': config.translate_options['2m'],  # 2 or more
        'energy': com,
        'variable': variable,
        'category': category,
        'phase_space': phase_space,
        'norm_method': norm_method,
        'lepton': channel.title(),
    }
    variable_template = config.variable_path_templates[
        variable].format(**inputs)

    template_category = category
    if category == 'QCD_shape' or category in config.rate_changing_systematics_names:
        template_category = 'central'
    if category in [config.vjets_theory_systematic_prefix + systematic for systematic in config.generator_systematics]:
        template_category = 'central'

    m.addSample(
        'TTJet',
        False,
        input=create_input(
            config, 'TTJet', variable, template_category, channel,
            variable_template, phase_space=phase_space, measurement=m,
        ),
    )
    m.addSample(
        'V+Jets',
        False,
        input=create_input(
            config, 'V+Jets', variable, template_category, channel,
            variable_template, phase_space=phase_space, measurement=m,
        ),
    )
    m.addSample(
        'SingleTop',
        False,
        input=create_input(
            config, 'SingleTop', variable, template_category, channel,
            variable_template, phase_space=phase_space, measurement=m,
        ),
    )
    m.addSample(
        'QCD',
        False,
        input=create_input(
            config, 'QCD', variable, template_category, channel,
            variable_template, phase_space=phase_space, measurement=m,
        ),
    )
    variable_template_data = variable_template.replace(
        met_type, config.translate_options['type1'])

    m.addSample(
        'data',
        False,
        input=create_input(
            config, 'data', variable, template_category, channel,
            variable_template_data, phase_space=phase_space, measurement=m,
        ),
    )

    m_qcd = Measurement(category)
    m_qcd.setVariable(variable)
    m_qcd.setCentreOfMassEnergy(com)

    qcd_template = get_qcd_template(config, variable, category, channel)

    # we want "measurement = m" here since all rate systematics should apply
    # to the control regions as well
    m_qcd.addSample(
        'TTJet',
        False,
        input=create_input(
            config, 'TTJet', variable, template_category, channel,
            qcd_template, phase_space=phase_space, measurement=m,
        ),
    )
    m_qcd.addSample(
        'V+Jets',
        False,
        input=create_input(
            config, 'V+Jets', variable, template_category, channel,
            qcd_template, phase_space=phase_space, measurement=m,
        ),
    )
    m_qcd.addSample(
        'SingleTop',
        False,
        input=create_input(
            config, 'SingleTop', variable, template_category, channel,
            qcd_template, phase_space=phase_space, measurement=m,
        ),
    )
    m_qcd.addSample(
        'QCD',
        False,
        input=create_input(
            config, 'QCD', variable, template_category, channel,
            qcd_template, phase_space=phase_space, measurement=m,
        ),
    )
    m_qcd.addSample(
        'data',
        False,
        input=create_input(
            config, 'data', variable, template_category, channel,
            qcd_template, phase_space=phase_space, measurement=m,
        ),
    )

    m.addShapeForSample('QCD', m_qcd, False)
    norm_qcd = deepcopy(m_qcd)
    # we want QCD shape and normalisation to be separate
    if category == 'QCD_shape':
        for sample in norm_qcd.samples.keys():
            tree = norm_qcd.samples[sample]['input'].tree_name
            if channel == 'electron':
                tree = tree.replace(config.electron_control_region_systematic,
                                    config.electron_control_region)
            else:
                tree = tree.replace(config.muon_control_region_systematic,
                                    config.muon_control_region)
            norm_qcd.samples[sample]['input'].tree_name = tree
    if 'QCD_cross_section' in category:
        for sample in norm_qcd.samples.keys():
            tree = norm_qcd.samples[sample]['input'].tree_name
            if channel == 'electron':
                tree = tree.replace(config.electron_control_region,
                                    config.electron_control_region_systematic)
            else:
                tree = tree.replace(config.muon_control_region,
                                    config.muon_control_region_systematic)
            norm_qcd.samples[sample]['input'].tree_name = tree

    m.addNormForSample('QCD', norm_qcd, False)

    if category in [config.vjets_theory_systematic_prefix + systematic for systematic in config.generator_systematics]:
        v_template_category = category.replace(
            config.vjets_theory_systematic_prefix, '')
        m_vjets = Measurement(category)
        m_vjets.setVariable(variable)
        m_vjets.setCentreOfMassEnergy(com)
        m_vjets.addSample(
            'V+Jets',
            False,
            input=create_input(
                config, 'V+Jets', variable, v_template_category,
                channel,
                variable_template,
                config.generator_systematic_vjets_templates[
                    v_template_category]),
            phase_space=phase_space, measurement=m,
        )
        m.addShapeForSample('V+Jets', m_vjets, False)

    inputs['channel'] = channel
    base_path = 'config/measurements/{norm_method}/{energy}TeV/'
    base_path += '{channel}/{variable}/{phase_space}/'
    if category == 'central':
        path = base_path + '{category}.json'
        m.toJSON(path.format(**inputs))
    else:
        if m.type == Systematic.SHAPE:
            inputs['type'] = 'shape_systematic'
        else:
            inputs['type'] = 'rate_systematic'
        if category in config.met_systematics_suffixes and category not in ['JES_up', 'JES_down', 'JER_up', 'JER_down']:
            inputs['category'] = met_type
        path = base_path + '{category}_{type}.json'
        m.toJSON(path.format(**inputs))
Example #2
0
def create_measurement(com, category, variable, channel, phase_space,
                       norm_method):
    if com == 13:
        # exclude non existing systematics
        if 'VJets' in category and 'scale' in category:
            print('Excluding {0} for now'.format(category))
            return
    config = XSectionConfig(com)
    met_type = get_met_type(category, config)
    should_not_run_systematic = category in config.met_systematics_suffixes and variable in config.variables_no_met and not 'JES' in category and not 'JER' in category
    if should_not_run_systematic:
        # no MET uncertainty on HT (but JES and JER of course)
        return

    m = None
    if category == 'central':
        m = Measurement(category)
    else:
        vjet_systematics = [
            config.vjets_theory_systematic_prefix + systematic
            for systematic in config.generator_systematics
        ]
        if category in config.categories_and_prefixes.keys() or \
                category in config.met_systematics_suffixes or \
                category in vjet_systematics:
            m = Systematic(category,
                           stype=Systematic.SHAPE,
                           affected_samples=config.samples)
        elif category in config.rate_changing_systematics_names:
            m = config.rate_changing_systematics_values[category]

        elif category == 'QCD_shape':
            m = Systematic(
                category,
                stype=Systematic.SHAPE,
                affected_samples=['QCD'],
            )

    m.setVariable(variable)
    m.setCentreOfMassEnergy(com)
    m.setChannel(channel)
    m.setMETType(met_type)

    inputs = {
        'channel': config.analysis_types[channel],
        'met_type': met_type,
        'selection': 'Ref selection',
        'btag': config.translate_options['2m'],  # 2 or more
        'energy': com,
        'variable': variable,
        'category': category,
        'phase_space': phase_space,
        'norm_method': norm_method,
        'lepton': channel.title(),
    }
    variable_template = config.variable_path_templates[variable].format(
        **inputs)

    template_category = category
    if category == 'QCD_shape' or category in config.rate_changing_systematics_names:
        template_category = 'central'
    if category in [
            config.vjets_theory_systematic_prefix + systematic
            for systematic in config.generator_systematics
    ]:
        template_category = 'central'

    m.addSample(
        'TTJet',
        False,
        input=create_input(
            config,
            'TTJet',
            variable,
            template_category,
            channel,
            variable_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m.addSample(
        'V+Jets',
        False,
        input=create_input(
            config,
            'V+Jets',
            variable,
            template_category,
            channel,
            variable_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m.addSample(
        'SingleTop',
        False,
        input=create_input(
            config,
            'SingleTop',
            variable,
            template_category,
            channel,
            variable_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m.addSample(
        'QCD',
        False,
        input=create_input(
            config,
            'QCD',
            variable,
            template_category,
            channel,
            variable_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    variable_template_data = variable_template.replace(
        met_type, config.translate_options['type1'])

    m.addSample(
        'data',
        False,
        input=create_input(
            config,
            'data',
            variable,
            template_category,
            channel,
            variable_template_data,
            phase_space=phase_space,
            measurement=m,
        ),
    )

    m_qcd = Measurement(category)
    m_qcd.setVariable(variable)
    m_qcd.setCentreOfMassEnergy(com)

    qcd_template = get_qcd_template(config, variable, category, channel)

    # we want "measurement = m" here since all rate systematics should apply
    # to the control regions as well
    m_qcd.addSample(
        'TTJet',
        False,
        input=create_input(
            config,
            'TTJet',
            variable,
            template_category,
            channel,
            qcd_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m_qcd.addSample(
        'V+Jets',
        False,
        input=create_input(
            config,
            'V+Jets',
            variable,
            template_category,
            channel,
            qcd_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m_qcd.addSample(
        'SingleTop',
        False,
        input=create_input(
            config,
            'SingleTop',
            variable,
            template_category,
            channel,
            qcd_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m_qcd.addSample(
        'QCD',
        False,
        input=create_input(
            config,
            'QCD',
            variable,
            template_category,
            channel,
            qcd_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )
    m_qcd.addSample(
        'data',
        False,
        input=create_input(
            config,
            'data',
            variable,
            template_category,
            channel,
            qcd_template,
            phase_space=phase_space,
            measurement=m,
        ),
    )

    m.addShapeForSample('QCD', m_qcd, False)
    norm_qcd = deepcopy(m_qcd)
    # we want QCD shape and normalisation to be separate
    if category == 'QCD_shape':
        for sample in norm_qcd.samples.keys():
            tree = norm_qcd.samples[sample]['input'].tree_name
            if channel == 'electron':
                tree = tree.replace(config.electron_control_region_systematic,
                                    config.electron_control_region)
            else:
                tree = tree.replace(config.muon_control_region_systematic,
                                    config.muon_control_region)
            norm_qcd.samples[sample]['input'].tree_name = tree
    if 'QCD_cross_section' in category:
        for sample in norm_qcd.samples.keys():
            tree = norm_qcd.samples[sample]['input'].tree_name
            if channel == 'electron':
                tree = tree.replace(config.electron_control_region,
                                    config.electron_control_region_systematic)
            else:
                tree = tree.replace(config.muon_control_region,
                                    config.muon_control_region_systematic)
            norm_qcd.samples[sample]['input'].tree_name = tree

    m.addNormForSample('QCD', norm_qcd, False)

    if category in [
            config.vjets_theory_systematic_prefix + systematic
            for systematic in config.generator_systematics
    ]:
        v_template_category = category.replace(
            config.vjets_theory_systematic_prefix, '')
        m_vjets = Measurement(category)
        m_vjets.setVariable(variable)
        m_vjets.setCentreOfMassEnergy(com)
        m_vjets.addSample(
            'V+Jets',
            False,
            input=create_input(
                config, 'V+Jets', variable, v_template_category, channel,
                variable_template, config.
                generator_systematic_vjets_templates[v_template_category]),
            phase_space=phase_space,
            measurement=m,
        )
        m.addShapeForSample('V+Jets', m_vjets, False)

    inputs['channel'] = channel
    base_path = 'config/measurements/{norm_method}/{energy}TeV/'
    base_path += '{channel}/{variable}/{phase_space}/'
    if category == 'central':
        path = base_path + '{category}.json'
        m.toJSON(path.format(**inputs))
    else:
        if m.type == Systematic.SHAPE:
            inputs['type'] = 'shape_systematic'
        else:
            inputs['type'] = 'rate_systematic'
        if category in config.met_systematics_suffixes and category not in [
                'JES_up', 'JES_down', 'JER_up', 'JER_down'
        ]:
            inputs['category'] = met_type
        path = base_path + '{category}_{type}.json'
        m.toJSON(path.format(**inputs))