Ejemplo n.º 1
0
def test_readme():
    momentum = from_root('TMath::Sqrt(X_PX**2 + X_PY**2 + X_PZ**2)')
    assert momentum.to_numexpr(
    ) == 'sqrt(((X_PX ** 2) + (X_PY ** 2) + (X_PZ ** 2)))'
    assert momentum.to_root(
    ) == 'TMath::Sqrt(((X_PX ** 2) + (X_PY ** 2) + (X_PZ ** 2)))'
    my_selection = from_numexpr('X_PT > 5 & (Mu_NHits > 3 | Mu_PT > 10)')
    assert my_selection.to_root(
    ) == '(X_PT > 5) && ((Mu_NHits > 3) || (Mu_PT > 10))'
    assert my_selection.to_numexpr(
    ) == '(X_PT > 5) & ((Mu_NHits > 3) | (Mu_PT > 10))'
    my_sum = from_auto('True + False')
    assert my_sum.to_root() == 'true + false'
    assert my_sum.to_numexpr() == 'True + False'
    my_check = from_auto('(X_THETA*TMath::DegToRad() > pi/4) && D_PE > 9.2')
    assert my_check.variables == {'D_PE', 'X_THETA'}
    assert my_check.named_constants == {'DEG2RAD', 'PI'}
    assert my_check.unnamed_constants == {'4', '9.2'}
    new_selection = (momentum > 100) and (my_check or (np.sqrt(my_sum) < 1))

    def numexpr_eval(string):
        return numexpr.evaluate(string,
                                local_dict=dict(X_THETA=1234, D_PE=678))

    assert pytest.approx(
        numexpr_eval(new_selection.to_numexpr()),
        numexpr_eval(
            '((X_THETA * 0.017453292519943295) > (3.141592653589793 / 4)) & (D_PE > 9.2)'
        ))
Ejemplo n.º 2
0
def test_unnamed_constants():
    assert from_root('pi').unnamed_constants == set()
    assert from_numexpr('2').unnamed_constants == {'2'}
    assert from_numexpr('2e-3').unnamed_constants == {'2e-3'}
    assert from_numexpr('A').unnamed_constants == set()
    assert from_numexpr('A + A').unnamed_constants == set()
    assert from_numexpr('A + B').unnamed_constants == set()
    assert from_numexpr('A + A*A - 3e7').unnamed_constants == {'3e7'}
    assert from_numexpr('arctan2(A, A)').unnamed_constants == set()
    assert from_numexpr('arctan2(A, B)').unnamed_constants == set()
    assert from_root('arctan2(A, pi)').unnamed_constants == set()
    assert from_numexpr('arctan2(arctan2(A, B), C)').unnamed_constants == set()
    for base, expect in [(UC('2'), {'2'}), (Variable('A'), set()), (NC(ConstantIDs.PI), set())]:
        expr = base
        for i in list(range(100)):
            expr = Expression(IDs.SQRT, expr)
        assert expr.unnamed_constants == expect
Ejemplo n.º 3
0
 def test():
     root_expression = from_root(root_input)
     numexpr_expression = from_numexpr(numexpr_input)
     assert_equal_expressions(root_expression, numexpr_expression)
     assert to_numexpr(root_expression) == to_numexpr(numexpr_expression)
     assert to_root(root_expression) == to_root(numexpr_expression)
     assert root_expression.to_numexpr() == numexpr_expression.to_numexpr()
     assert root_expression.to_root() == numexpr_expression.to_root()
Ejemplo n.º 4
0
def test_get_variables():
    assert from_root('pi').variables == set()
    assert from_numexpr('2').variables == set()
    assert from_numexpr('2e-3').variables == set()
    assert from_numexpr('A').variables == set(['A'])
    assert from_numexpr('A + A').variables == set(['A'])
    assert from_numexpr('A + B').variables == set(['A', 'B'])
    assert from_numexpr('A + A*A - 3e7').variables == set(['A'])
    assert from_numexpr('arctan2(A, A)').variables == set(['A'])
    assert from_numexpr('arctan2(A, B)').variables == set(['A', 'B'])
    assert from_root('arctan2(A, pi)').variables == set(['A'])
    assert from_numexpr('arctan2(arctan2(A, B), C)').variables == set(
        ['A', 'B', 'C'])
    for base, expect in [(UC('2'), set()), (Variable('A'), set(['A'])),
                         (NC(ConstantIDs.PI), set())]:
        expr = base
        for i in list(range(100)):
            expr = Expression(IDs.SQRT, expr)
        assert expr.variables == expect
Ejemplo n.º 5
0
def parse_args(args):
    parser = argparse.ArgumentParser(
        description='Convert between different types of formulae')

    from_group = parser.add_mutually_exclusive_group(required=True)
    from_group.add_argument('--from-root')
    from_group.add_argument('--from-numexpr')

    to_group = parser.add_mutually_exclusive_group(required=True)
    to_group.add_argument('--to-root', action='store_true')
    to_group.add_argument('--to-numexpr', action='store_true')
    to_group.add_argument('--variables', action='store_true')
    to_group.add_argument('--named-constants', action='store_true')
    to_group.add_argument('--unnamed-constants', action='store_true')

    args = parser.parse_args(args)
    if args.from_root is not None:
        expression = from_root(args.from_root)
    elif args.from_numexpr is not None:
        expression = from_numexpr(args.from_numexpr)
    else:
        raise NotImplementedError()

    if args.to_root:
        result = to_root(expression)
    elif args.to_numexpr:
        result = to_numexpr(expression)
    elif args.variables:
        result = '\n'.join(sorted(expression.variables))
    elif args.named_constants:
        result = '\n'.join(sorted(expression.named_constants))
    elif args.unnamed_constants:
        result = '\n'.join(sorted(expression.unnamed_constants))
    else:
        raise NotImplementedError()

    return result
Ejemplo n.º 6
0
def get_root_from_root_file(file_name, tree_name, kwargs):
    """Load a ROOT tree into a `ROOT.RooDataSet`.

    Needed keys in `kwargs` are:
        + `name`: Name of the `RooDataSet`.
        + `title`: Title of the `RooDataSet`.

    Optional keys are:
        + `variables`: List of variables to load.
        + `selection`: Selection to apply.
        + `ranges`: Range to apply to some variables.

    Arguments:
        file_name (str): File to load.
        tree_name (str): Tree to load.
        kwargs (dict): Extra configuration.

    Return:
        ROOT.RooDataSet: ROOT file converted to RooDataSet.

    Raise:
        KeyError: If there are errors in `kwargs`.
        ValueError: If the requested variables cannot be found in the input file.
        OSError: If the ROOT file cannot be found.

    """
    def get_list_of_leaves(tree):
        """Get list of leave names from a tree matching a certain regex.

        Arguments:
            tree (`ROOT.TTree`): Tree to extract the leaves from.

        Return:
            list: Leaves of the tree.

        """
        object_list = tree.GetListOfLeaves()
        it = object_list.MakeIterator()
        output = set()
        for _ in range(object_list.GetSize()):
            obj = it.Next()
            if obj:
                output.add(obj.GetName())
        return output

    logger.debug("Loading ROOT file in RooDataSet format -> %s:%s", file_name,
                 tree_name)
    if not os.path.exists(file_name):
        raise OSError("Cannot find input file -> {}".format(file_name))
    try:
        name = kwargs['name']
        title = kwargs.get('title', name)
    except KeyError as error:
        raise KeyError("Missing configuration key -> {}".format(error))
    tfile = ROOT.TFile.Open(file_name)
    tree = tfile.Get(tree_name)
    if not tree:
        raise KeyError(
            "Cannot find tree in input file -> {}".format(tree_name))
    leaves = get_list_of_leaves(tree)
    variables = set(kwargs.get('variables', leaves))
    # Acceptance
    if 'acceptance' in kwargs:
        raise NotImplementedError(
            "Acceptance weights are not implemented for ROOT files")
    # Check weights
    try:
        weight_var, weights_to_normalize, weights_not_to_normalize = _analyze_weight_config(
            kwargs)
    except KeyError:
        raise KeyError("Badly specified weights")
    if variables and weight_var:
        variables = set(variables) | set(weights_to_normalize) | set(
            weights_not_to_normalize)
    # Crosscheck leaves
    if variables - leaves:
        raise ValueError("Cannot find leaves in input -> {}".format(variables -
                                                                    leaves))
    selection = kwargs.get('selection')
    leave_set = ROOT.RooArgSet()
    leave_list = []
    if selection:
        selection_expr = formulate.from_root(selection)
        for var in selection_expr.variables.union(variables):
            leave_list.append(ROOT.RooRealVar(var, var, 0.0))
            leave_set.add(leave_list[-1])
        name = ''.join(random.SystemRandom().choice(string.ascii_letters +
                                                    string.digits)
                       for _ in range(10))
        temp_ds = ROOT.RooDataSet(name, name, leave_set,
                                  ROOT.RooFit.Import(tree),
                                  ROOT.RooFit.Cut(selection))
        destruct_object(tree)
        tree = temp_ds
    var_set = ROOT.RooArgSet()
    var_list = {}
    for var in variables:
        var_list[var] = ROOT.RooRealVar(var, var, 0.0)
        var_set.add(var_list[var])
    if kwargs.get('ranges'):
        for var_name, range_val in kwargs['ranges'].items():
            if var_name not in var_list:
                raise KeyError(
                    "Range specified for a variable not included in the dataset -> {}"
                    .format(var_name))
            try:
                if isinstance(range_val, str):
                    min_, max_ = range_val.split()
                else:
                    min_, max_ = range_val
            except ValueError:
                raise KeyError(
                    "Malformed range specification for {} -> {}".format(
                        var_name, range_val))
            var_set[var_name].setMin(float(min_))
            var_set[var_name].setMax(float(max_))
    dataset = ROOT.RooDataSet(name, title, var_set, ROOT.RooFit.Import(tree))
    if weight_var:
        # Weights to normalize
        to_normalize_w = ROOT.RooFormulaVar(
            "{}_not_normalized".format(weight_var),
            "{}_not_normalized".format(weight_var),
            "*".join(weights_to_normalize),
            list_to_rooarglist(var_list[weight]
                               for weight in weights_to_normalize))
        var_set.append(to_normalize_w)
        dataset.addColumn(to_normalize_w)
        sum_weights = sum(
            dataset.get(entry)["{}_not_normalized".format(
                weight_var)].getVal() for entry in dataset.sumEntries())
        normalized_w = ROOT.RooFormulaVar(
            "{}_normalized".format(weight_var),
            "{}_normalized".format(weight_var),
            "{}_not_normalized/{}".format(weight_var, sum_weights),
            ROOT.RooArgList(to_normalize_w))
        var_set.append(normalized_w)
        dataset.addColumn(normalized_w)
        # Non-normalized weights
        weights = ROOT.RooFormulaVar(
            weight_var, weight_var,
            "*".join(weights_not_to_normalize +
                     ["{}_normalized".format(weight_var)]),
            list_to_rooarglist(
                [var_list[weight]
                 for weight in weights_not_to_normalize] + [normalized_w]))
        var_set.append(weights)
        dataset.addColumn(weights)
        dataset_w = ROOT.RooDataSet(name, title, var_set,
                                    ROOT.RooFit.Import(dataset),
                                    ROOT.RooFit.WeightVar(weight_var))
        destruct_object(dataset)
        dataset = dataset_w
    # ROOT Cleanup
    destruct_object(tree)
    tfile.Close()
    destruct_object(tfile)
    if selection:
        for leave in leave_list:
            destruct_object(leave)
    for var in variables:
        destruct_object(var_list[var])
    # Let's return
    dataset.SetName(name)
    dataset.SetTitle(title)
    return dataset