def split_sample_reference(s):
    """
    Split a '[RUN][:PROJECT[/SAMPLE]]' reference id

    Decomposes a reference id of the form:

    [RUN][:PROJECT[/SAMPLE]]

    where:

    - RUN is a run identifier (either a run name e.g.
      '201027_SN00284_0000161_AHXXJHJH', a reference id e.g.
      'HISEQ_201027/161#122', or a path to an analysis
      directory)
    - PROJECT is the name of a project within the run, and
    - SAMPLE is a sample name.

    A subset of elements can be present, in which case
    the missing components will be returned as None.

    Returns:
      Tuple: tuple of the form (RUN,PROJECT,SAMPLE)
        extracted from the supplied reference id;
        missing elements are set to None.
    """
    # Try to extract run name first
    if ':' in s:
        run,name = s.split(':')
    else:
        # Either a run or a sample specification
        if '#' in s:
            # Definitely a run reference id
            # Note: this test is quite weak!
            run = s
            name = None
        else:
            # Assume it's PROJECT[/SAMPLE]
            run = None
            name = s
    # Extract project and sample names
    if name:
        if '/' in name:
            # Split PROJECT/SAMPLE
            project,sample = name.split('/')
        elif run is None:
            # There was no leading RUN
            # so assume this is just SAMPLE
            project = None
            sample = name
        else:
            # There was a leading RUN
            # so assume this is just PROJECT
            project = name
            sample = None
    else:
        # RUN but no PROJECT and/or SAMPLE
        project = None
        sample = None
    # Normalise outputs: make sure empty values
    # are replaced with None
    run = run if run else None
    project = project if project else None
    sample = sample if sample else None
    return (run,project,sample)