Read in a daily NOAA SURFRAD[1] file.

    Parameters
    ----------
    filename: str
        Filepath or url.
    map_variables: bool
        When true, renames columns of the Dataframe to pvlib variable names
        where applicable. See variable SURFRAD_COLUMNS.

    Returns
    -------
    Tuple of the form (data, metadata).

    data: Dataframe
        Dataframe with the fields found below.
    metadata: dict
        Site metadata included in the file.

    Notes
    -----
    Metadata dictionary includes the following fields:

    ===============  ======  ===============
    Key              Format  Description
    ===============  ======  ===============
    station          String  site name
    latitude         Float   site latitude
    longitude        Float   site longitude
    elevation        Int     site elevation
    surfrad_version  Int     surfrad version
    tz               String  Timezone (UTC)
    ===============  ======  ===============

    Dataframe includes the following fields:

    =======================  ======  ==========================================
    raw, mapped              Format  Description
    =======================  ======  ==========================================
    **Mapped field names are returned when the map_variables argument is True**
    ---------------------------------------------------------------------------
    year                     int     year as 4 digit int
    jday                     int     day of year 1-365(or 366)
    month                    int     month (1-12)
    day                      int     day of month(1-31)
    hour                     int     hour (0-23)
    minute                   int     minute (0-59)
    dt                       float   decimal time i.e. 23.5 = 2330
    zen, solar_zenith        float   solar zenith angle (deg)
    **Fields below have associated qc flags labeled <field>_flag.**
    ---------------------------------------------------------------------------
    dw_solar, ghi            float   downwelling global solar(W/m^2)
    uw_solar                 float   updownwelling global solar(W/m^2)
    direct_n, dni            float   direct normal solar (W/m^2)
    diffuse, dhi             float   downwelling diffuse solar (W/m^2)
    dw_ir                    float   downwelling thermal infrared (W/m^2)
    dw_casetemp              float   downwelling IR case temp (K)
    dw_dometemp              float   downwelling IR dome temp (K)
    uw_ir                    float   upwelling thermal infrared (W/m^2)
    uw_casetemp              float   upwelling IR case temp (K)
    uw_dometemp              float   upwelling IR case temp (K)
    uvb                      float   global uvb (miliWatts/m^2)
    par                      float   photosynthetically active radiation(W/m^2)
    netsolar                 float   net solar (dw_solar - uw_solar) (W/m^2)
    netir                    float   net infrared (dw_ir - uw_ir) (W/m^2)
    totalnet                 float   net radiation (netsolar+netir) (W/m^2)
    temp, temp_air           float   10-meter air temperature (?C)
    rh, relative_humidity    float   relative humidity (%)
    windspd, wind_speed      float   wind speed (m/s)
    winddir, wind_direction  float   wind direction (deg, clockwise from north)
    pressure                 float   station pressure (mb)
    =======================  ======  ==========================================

    See README files located in the station directories in the SURFRAD
    data archives[2] for details on SURFRAD daily data files.

    References
    ----------
    [1] NOAA Earth System Research Laboratory Surface Radiation Budget Network
        `SURFRAD Homepage <https://www.esrl.noaa.gov/gmd/grad/surfrad/>`_
    [2] NOAA SURFRAD Data Archive
        `SURFRAD Archive <ftp://aftp.cmdl.noaa.gov/data/radiation/surfrad/>`_

def read_surfrad(filename, map_variables=True):
    """Read in a daily NOAA SURFRAD[1] file.

    Parameters
    ----------
    filename: str
        Filepath or url.
    map_variables: bool
        When true, renames columns of the Dataframe to pvlib variable names
        where applicable. See variable SURFRAD_COLUMNS.

    Returns
    -------
    Tuple of the form (data, metadata).

    data: Dataframe
        Dataframe with the fields found below.
    metadata: dict
        Site metadata included in the file.

    Notes
    -----
    Metadata dictionary includes the following fields:

    ===============  ======  ===============
    Key              Format  Description
    ===============  ======  ===============
    station          String  site name
    latitude         Float   site latitude
    longitude        Float   site longitude
    elevation        Int     site elevation
    surfrad_version  Int     surfrad version
    tz               String  Timezone (UTC)
    ===============  ======  ===============

    Dataframe includes the following fields:

    =======================  ======  ==========================================
    raw, mapped              Format  Description
    =======================  ======  ==========================================
    **Mapped field names are returned when the map_variables argument is True**
    ---------------------------------------------------------------------------
    year                     int     year as 4 digit int
    jday                     int     day of year 1-365(or 366)
    month                    int     month (1-12)
    day                      int     day of month(1-31)
    hour                     int     hour (0-23)
    minute                   int     minute (0-59)
    dt                       float   decimal time i.e. 23.5 = 2330
    zen, solar_zenith        float   solar zenith angle (deg)
    **Fields below have associated qc flags labeled <field>_flag.**
    ---------------------------------------------------------------------------
    dw_solar, ghi            float   downwelling global solar(W/m^2)
    uw_solar                 float   updownwelling global solar(W/m^2)
    direct_n, dni            float   direct normal solar (W/m^2)
    diffuse, dhi             float   downwelling diffuse solar (W/m^2)
    dw_ir                    float   downwelling thermal infrared (W/m^2)
    dw_casetemp              float   downwelling IR case temp (K)
    dw_dometemp              float   downwelling IR dome temp (K)
    uw_ir                    float   upwelling thermal infrared (W/m^2)
    uw_casetemp              float   upwelling IR case temp (K)
    uw_dometemp              float   upwelling IR case temp (K)
    uvb                      float   global uvb (miliWatts/m^2)
    par                      float   photosynthetically active radiation(W/m^2)
    netsolar                 float   net solar (dw_solar - uw_solar) (W/m^2)
    netir                    float   net infrared (dw_ir - uw_ir) (W/m^2)
    totalnet                 float   net radiation (netsolar+netir) (W/m^2)
    temp, temp_air           float   10-meter air temperature (?C)
    rh, relative_humidity    float   relative humidity (%)
    windspd, wind_speed      float   wind speed (m/s)
    winddir, wind_direction  float   wind direction (deg, clockwise from north)
    pressure                 float   station pressure (mb)
    =======================  ======  ==========================================

    See README files located in the station directories in the SURFRAD
    data archives[2] for details on SURFRAD daily data files.

    References
    ----------
    [1] NOAA Earth System Research Laboratory Surface Radiation Budget Network
        `SURFRAD Homepage <https://www.esrl.noaa.gov/gmd/grad/surfrad/>`_
    [2] NOAA SURFRAD Data Archive
        `SURFRAD Archive <ftp://aftp.cmdl.noaa.gov/data/radiation/surfrad/>`_
    """
    if filename.startswith('ftp'):
        req = Request(filename)
        response = urlopen(req)
        file_buffer = io.StringIO(response.read().decode(errors='ignore'))
    else:
        file_buffer = open(filename, 'r')

    # Read and parse the first two lines to build the metadata dict.
    station = file_buffer.readline()
    file_metadata = file_buffer.readline()

    metadata_list = file_metadata.split()
    metadata = {}
    metadata['name'] = station.strip()
    metadata['latitude'] = float(metadata_list[0])
    metadata['longitude'] = float(metadata_list[1])
    metadata['elevation'] = float(metadata_list[2])
    metadata['surfrad_version'] = int(metadata_list[-1])
    metadata['tz'] = 'UTC'

    data = pd.read_csv(file_buffer, delim_whitespace=True,
                       header=None, names=SURFRAD_COLUMNS)
    file_buffer.close()

    data = format_index(data)
    missing = data == -9999.9
    data = data.where(~missing, np.NaN)

    if map_variables:
        data.rename(columns=VARIABLE_MAP, inplace=True)
    return data, metadata