def load_projections(projections_file):
    """
    Loads projections defined in the given `projections_file`.

    The `projections_file` is expected to be in the following format::

        old_label_1 | new_label_1
        old_label_1 old_label_2 | new_label_2
        old_label_3 |

    You can define one projection per line. Each projection starts with a list of one or multiple
    old labels (separated by a single whitespace) that are separated from the new label by a pipe
    (`|`). In the code above, the segment labeled with `old_label_1` will be labeled with
    `new_label_1` after applying the projection. Segments that are labeled with `old_label_1`
    **and** `old_label_2` concurrently are relabeled to `new_label_2`. All segments labeled with
    `old_label_3` are dropped. Combinations of multiple labels are automatically sorted in natural
    order.

    Args:
        projections_file (str): Path to the file with projections

    Returns:
        dict: Dictionary where the keys are tuples of labels to project to the key's value

    Example:
        >>> load_projections('/path/to/projections.txt')
        {('b',): 'foo', ('a', 'b'): 'a_b', ('a',): 'bar'}
    """
    projections = {}
    for parts in textfile.read_separated_lines_generator(projections_file, '|'):
        combination = tuple(sorted([label.strip() for label in parts[0].split(' ')]))
        new_label = parts[1].strip()

        projections[combination] = new_label

    return projections
Loads projections defined in the given `projections_file`.

    The `projections_file` is expected to be in the following format::

        old_label_1 | new_label_1
        old_label_1 old_label_2 | new_label_2
        old_label_3 |

    You can define one projection per line. Each projection starts with a list of one or multiple
    old labels (separated by a single whitespace) that are separated from the new label by a pipe
    (`|`). In the code above, the segment labeled with `old_label_1` will be labeled with
    `new_label_1` after applying the projection. Segments that are labeled with `old_label_1`
    **and** `old_label_2` concurrently are relabeled to `new_label_2`. All segments labeled with
    `old_label_3` are dropped. Combinations of multiple labels are automatically sorted in natural
    order.

    Args:
        projections_file (str): Path to the file with projections

    Returns:
        dict: Dictionary where the keys are tuples of labels to project to the key's value

    Example:
        >>> load_projections('/path/to/projections.txt')
        {('b',): 'foo', ('a', 'b'): 'a_b', ('a',): 'bar'}