def main():
    '''
    1 - Read Config file for normalisation measurement
    2 - Run measurement
    3 - Combine measurement before unfolding
    '''
    results = {}

    # config file template
    input_template = 'config/measurements/background_subtraction/{com}TeV/{ch}/{var}/{ps}/'

    ps = 'FullPS'
    if args.visiblePS:
        ps = 'VisiblePS'

    for ch in ['electron', 'muon']:
        for var in measurement_config.variables:
            if args.variable not in var: continue

            # Create measurement_filepath
            measurement_filepath = input_template.format(
                com = args.CoM,
                ch = ch,
                var = var,
                ps = ps,
            )
            
            # Get all config files in measurement_filepath
            measurement_files = get_files_in_path(measurement_filepath, file_ending='.json')

            for f in sorted(measurement_files):
                if args.test:
                    if 'central' not in f: continue
                print('Processing file ' + f)
                # Read in Measurement JSON
                config = read_data_from_JSON(f)

                if 'electron' in ch:
                    # Create Measurement Class using JSON
                    electron_measurement = Measurement(config)
                    electron_measurement.calculate_normalisation()
                    electron_measurement.save(ps)
                elif 'muon' in ch:
                    # Create Measurement Class using JSON
                    muon_measurement = Measurement(config)
                    muon_measurement.calculate_normalisation()
                    muon_measurement.save(ps)
                # break

    # Combining the channels before unfolding
    combined_measurement = electron_measurement
    combined_measurement.combine(muon_measurement)
    combined_measurement.save(ps)
    return
def main():
    # construct categories from files:
    input_template = options.input + '{energy}TeV/{channel}/{variable}/{phase_space}/*.json'
    categories = ['QCD_shape']
    categories.extend(measurement_config.categories_and_prefixes.keys())
    categories.extend(measurement_config.rate_changing_systematics_names)
    categories.extend([measurement_config.vjets_theory_systematic_prefix +
                       systematic for systematic in measurement_config.generator_systematics])

    phase_space = 'FullPS'
    if options.visiblePS:
        phase_space = 'VisiblePS'
    results = {}
    for channel in ['electron', 'muon']:
        inputs = {
            'energy': options.CoM,
            'channel': channel,
            'variable': variable,
            'phase_space': phase_space,
        }
        measurement_files = glob.glob(input_template.format(**inputs))
        for f in sorted(measurement_files):
            print('Processing file ' + f)
            measurement = Measurement.fromJSON(f)
            # for each measurement
            norm = TTJetNormalisation(
                config=measurement_config,
                measurement=measurement,
                method=TTJetNormalisation.BACKGROUND_SUBTRACTION,
                phase_space=phase_space,
            )
            norm.calculate_normalisation()
            mylog.info('Saving results to {0}'.format(output_path))
            norm.save(output_path)
            # store results for later combination
            r_name = f.replace(channel, '')
            if not results.has_key(r_name):
                results[r_name] = [norm]
            else:
                results[r_name].append(norm)

    for f, r_list in results.items():
        if not len(r_list) == 2:
            msg = 'Only found results ({0}) for one channel, not combining.'
            mylog.warn(msg.format(f))
            continue
        n1, n2 = r_list
        n1.combine(n2)
        n1.save(output_path)
def main():
    # construct categories from files:
    input_template = args.input + '{energy}TeV/{channel}/{variable}/{phase_space}/'

    phase_space = 'FullPS'
    if args.visiblePS:
        phase_space = 'VisiblePS'
    results = {}

    for channel in ['electron', 'muon']:
        measurement_filepath = input_template.format(
            energy=args.CoM,
            channel=channel,
            variable=variable,
            phase_space=phase_space,
        )
        measurement_files = get_files_in_path(measurement_filepath,
                                              file_ending='.json')

        for f in sorted(measurement_files):
            if args.test and 'central' not in f: continue

            print('Processing file ' + f)
            measurement = Measurement.fromJSON(f)
            # for each measurement
            norm = TTJetNormalisation(
                config=measurement_config,
                measurement=measurement,
                phase_space=phase_space,
            )
            norm.calculate_normalisation()
            mylog.info('Saving results to {0}'.format(output_path))
            norm.save(output_path)
            # store results for later combination
            r_name = f.replace(channel, '')
            if not results.has_key(r_name):
                results[r_name] = [norm]
            else:
                results[r_name].append(norm)

    for f, r_list in results.items():
        if not len(r_list) == 2:
            msg = 'Only found results ({0}) for one channel, not combining.'
            mylog.warn(msg.format(f))
            continue
        n1, n2 = r_list
        n1.combine(n2)
        n1.save(output_path)
def main():
    # construct categories from files:
    input_template = args.input + '{energy}TeV/{channel}/{variable}/{phase_space}/'

    phase_space = 'FullPS'
    if args.visiblePS:
        phase_space = 'VisiblePS'
    results = {}

    for channel in ['electron', 'muon']:
        measurement_filepath = input_template.format(
            energy = args.CoM,
            channel = channel,
            variable = variable,
            phase_space = phase_space,
        )
        measurement_files = get_files_in_path(measurement_filepath, file_ending='.json')

        for f in sorted(measurement_files):
            if args.test and 'central' not in f: continue
            
            print('Processing file ' + f)
            measurement = Measurement.fromJSON(f)
            # for each measurement
            norm = TTJetNormalisation(
                config=measurement_config,
                measurement=measurement,
                phase_space=phase_space,
            )
            norm.calculate_normalisation()
            mylog.info('Saving results to {0}'.format(output_path))
            norm.save(output_path)
            # store results for later combination
            r_name = f.replace(channel, '')
            if not results.has_key(r_name):
                results[r_name] = [norm]
            else:
                results[r_name].append(norm)

    for f, r_list in results.items():
        if not len(r_list) == 2:
            msg = 'Only found results ({0}) for one channel, not combining.'
            mylog.warn(msg.format(f))
            continue
        n1, n2 = r_list
        n1.combine(n2)
        n1.save(output_path)
def getControlRegionHistogramsFromFile(file):
	config = read_data_from_JSON(file)
	measurement = Measurement( config )
	return measurement.cr_histograms
def main():
    '''
    1 - Read Config file for normalisation measurement
    2 - Run measurement
    3 - Combine measurement before unfolding
    '''
    results = {}

    # config file template
    input_template          = 'config/measurements/background_subtraction/{com}TeV/{ch}/{var}/{ps}/'
    output_folder_template  = 'data/normalisation/background_subtraction/{com}TeV/{var}/{ps}/{cat}/'

    ps = 'FullPS'
    if args.visiblePS:
        ps = 'VisiblePS'

    channels = [
        'electron', 
        'muon',
    ]

    for ch in channels:
        for var in measurement_config.variables:
            if not args.variable == var: continue
            qcd_transfer_factor = {}

            # Create measurement_filepath
            measurement_filepath = input_template.format(
                com = args.CoM,
                ch = ch,
                var = var,
                ps = ps,
            )
            
            # Get all config files in measurement_filepath
            measurement_files = get_files_in_path(measurement_filepath, file_ending='.json')

            for f in sorted(measurement_files):
                if args.test:
                    if 'central' not in f: continue
                print('Processing file ' + f)
                sample = get_filename_without_extension(f)

                # Read in Measurement JSON
                config = read_data_from_JSON(f)

                if 'electron' in ch:
                    # Create Measurement Class using JSON
                    electron_measurement = Measurement(config)
                    electron_measurement.calculate_normalisation()
                    electron_measurement.save(ps)
                    qcd_transfer_factor[sample] = [electron_measurement.t_factor]

                elif 'muon' in ch:
                    # Create Measurement Class using JSON
                    muon_measurement = Measurement(config)
                    muon_measurement.calculate_normalisation()
                    muon_measurement.save(ps)
                    qcd_transfer_factor[sample] = [muon_measurement.t_factor]

            output_folder = output_folder_template.format(
                com = args.CoM,  var = var,
                ps  = ps,   cat = 'central',
            )
            store_transfer_factor(qcd_transfer_factor, output_folder, ch)
    return
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))
def main():
    '''
    1 - Read Config file for normalisation measurement
    2 - Run measurement
    3 - Combine measurement before unfolding
    '''
    results = {}

    # config file template
    input_template = 'config/measurements/background_subtraction/{com}TeV/{ch}/{var}/{ps}/'
    output_folder_template = 'data/normalisation/background_subtraction/{com}TeV/{var}/{ps}/{cat}/'

    ps = 'FullPS'
    if args.visiblePS:
        ps = 'VisiblePS'

    channels = [
        'electron',
        'muon',
    ]

    for ch in channels:
        for var in measurement_config.variables:
            if not args.variable == var: continue
            qcd_transfer_factor = {}

            # Create measurement_filepath
            measurement_filepath = input_template.format(
                com=args.CoM,
                ch=ch,
                var=var,
                ps=ps,
            )

            # Get all config files in measurement_filepath
            measurement_files = get_files_in_path(measurement_filepath,
                                                  file_ending='.json')

            for f in sorted(measurement_files):
                if args.test:
                    if 'central' not in f: continue
                print('Processing file ' + f)
                sample = get_filename_without_extension(f)

                # Read in Measurement JSON
                config = read_data_from_JSON(f)

                if 'electron' in ch:
                    # Create Measurement Class using JSON
                    electron_measurement = Measurement(config)
                    electron_measurement.calculate_normalisation()
                    electron_measurement.save(ps)
                    qcd_transfer_factor[sample] = [
                        electron_measurement.t_factor
                    ]

                elif 'muon' in ch:
                    # Create Measurement Class using JSON
                    muon_measurement = Measurement(config)
                    muon_measurement.calculate_normalisation()
                    muon_measurement.save(ps)
                    qcd_transfer_factor[sample] = [muon_measurement.t_factor]

            output_folder = output_folder_template.format(
                com=args.CoM,
                var=var,
                ps=ps,
                cat='central',
            )
            store_transfer_factor(qcd_transfer_factor, output_folder, ch)
    return
Example #9
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))