Read University of Oregon SRML[1] 1min .tsv file into pandas dataframe.

    Parameters
    ----------
    filename: str
        filepath or url to read for the tsv file.

    Returns
    -------
    data: Dataframe
        A dataframe with datetime index and all of the variables listed
        in the `VARIABLE_MAP` dict inside of the map_columns function,
        along with their associated quality control flags.

    Notes
    -----
    The time index is shifted back one minute to account for 2400 hours,
    and to avoid time parsing errors on leap years. The returned data
    values should be understood to occur during the interval from the
    time of the row until the time of the next row. This is consistent
    with pandas' default labeling behavior.

    See SRML's `Archival Files`_ page for more information.

    .. _Archival Files: http://solardat.uoregon.edu/ArchivalFiles.html

    References
    ----------
    [1] University of Oregon Solar Radiation Monitoring Laboratory
        `http://solardat.uoregon.edu/ <http://solardat.uoregon.edu/>`_

def read_srml(filename):
    """
    Read University of Oregon SRML[1] 1min .tsv file into pandas dataframe.

    Parameters
    ----------
    filename: str
        filepath or url to read for the tsv file.

    Returns
    -------
    data: Dataframe
        A dataframe with datetime index and all of the variables listed
        in the `VARIABLE_MAP` dict inside of the map_columns function,
        along with their associated quality control flags.

    Notes
    -----
    The time index is shifted back one minute to account for 2400 hours,
    and to avoid time parsing errors on leap years. The returned data
    values should be understood to occur during the interval from the
    time of the row until the time of the next row. This is consistent
    with pandas' default labeling behavior.

    See SRML's `Archival Files`_ page for more information.

    .. _Archival Files: http://solardat.uoregon.edu/ArchivalFiles.html

    References
    ----------
    [1] University of Oregon Solar Radiation Monitoring Laboratory
        `http://solardat.uoregon.edu/ <http://solardat.uoregon.edu/>`_
    """
    tsv_data = pd.read_csv(filename, delimiter='\t')
    data = format_index(tsv_data)
    # Drop day of year and time columns
    data = data[data.columns[2:]]

    data = data.rename(columns=map_columns)

    # Quality flag columns are all labeled 0 in the original data. They
    # appear immediately after their associated variable and are suffixed
    # with an integer value when read from the file. So we map flags to
    # the preceding variable with a '_flag' suffix.
    #
    # Example:
    #   Columns ['ghi_0', '0.1', 'temp_air_2', '0.2']
    #
    #   Yields a flag_label_map of:
    #       { '0.1': 'ghi_0_flag',
    #         '0.2': 'temp_air_2'}
    #
    columns = data.columns
    flag_label_map = {flag: columns[columns.get_loc(flag) - 1] + '_flag'
                      for flag in columns[1::2]}
    data = data.rename(columns=flag_label_map)

    # Mask data marked with quality flag 99 (bad or missing data)
    for col in columns[::2]:
        missing = data[col + '_flag'] == 99
        data[col] = data[col].where(~(missing), np.NaN)
    return data