Beispiel #1
0
def convert_to_durinal(data: pd.DataFrame,
                       coords: tuple,
                       factor=1) -> pd.DataFrame:
    """

    Parameters
    ----------
    data : Pandas dataframe
        with datetimeindex and column 'global_horizontal'
    coords : Tuple
        coordinates of pv station (lat, lon)
    factor : int
        by which the incoming data is multiplied, used to convert W to Wh/day
    Returns
    -------
    Pandas dataframe
        with hourly values and column 'global horizontal' following a sinusoidal function
    """
    def _upsample_df_single_day(indf):
        """Upsamples dataframe to hourly values but only fills the days that were in the original dataframe
        and drops all other rows
        """
        df = indf.copy()
        # add line at the end so resample treats it like a whole day:
        df.loc[df.index[-1] + pd.Timedelta("1D")] = np.full(len(df.columns), 0)
        df = df.resample(rule="1H").pad(limit=23)
        # removing last line again:
        df = df.drop(df.index[-1])
        return df.dropna(how="all")

    # Calculate sunset and sunrise times and write to dataframe:
    if "rise_set" not in data:
        data["rise_set"] = trigon.sun_rise_set_times(data.index, coords)
        data["sunrise_h"] = data["rise_set"].map(
            lambda x: decimal_hours(x[0], "sunrise"))
        data["sunset_h"] = data["rise_set"].map(
            lambda x: decimal_hours(x[1], "sunset"))
    # Upsample the data to hourly timestamps and calculate the hourly irradiance:
    data.loc[:, "global_horizontal_day"] = factor * data[
        "global_horizontal"].copy()
    daily = _upsample_df_single_day(data)
    daily["hour"] = daily.index.hour
    daily["global_horizontal"] = cyth.apply_csinus_func(
        daily["sunrise_h"].values,
        daily["sunset_h"].values,
        daily["hour"].values,
        daily["global_horizontal_day"].values,
    )
    mean_daily = daily["global_horizontal"].resample(rule="D").mean()
    corr_fact = mean_daily / data["global_horizontal"]
    ups_corr_fact = _upsample_df_single_day(corr_fact.to_frame())
    daily_corr = daily["global_horizontal"] / ups_corr_fact["global_horizontal"]
    daily["global_horizontal"] = daily_corr

    return daily
Beispiel #2
0
def run(hourly_clearness, coords, rise_set_times=None):
    """Run the BRL model

    Parameters
    ----------
    hourly_clearness : pandas Series
        Hourly clearness indices with a datetime index.
    coords : 2-tuple of floats or ints
        Latitude and longitude
    rise_set_times : list
        List of (sunrise, sunset) time tuples, if not given, is
        calculated here.

    Returns
    -------
    result : pandas Series
        Diffuse fractions with the same datetime index as hourly_clearness.

    """
    if rise_set_times is None:
        rise_set_times = trigon.sun_rise_set_times(hourly_clearness.index, coords)

    obs = ephem.Observer()
    obs.lat = str(coords[0])
    obs.lon = str(coords[1])

    diffuse_fractions = []
    for i in range(0, len(hourly_clearness), 24):
        # for entry in list in hourly clearness indices:
        ks = hourly_clearness.iloc[i : i + 24].tolist()
        obs.date = hourly_clearness.index[i]
        # These are indexed by day, so need to scale the index
        sunrise, sunset = rise_set_times[int(i / 24)]
        results = _daily_diffuse(obs, ks, sunrise, sunset)
        diffuse_fractions.extend(results)
    return pd.Series(diffuse_fractions, index=hourly_clearness.index)
Beispiel #3
0
def add_kd_run_gsee(df: pd.DataFrame, coords: dict, frequency: str,
                    params: dict) -> pd.Series:
    """
    Calculates diffuse fraction with extraterrestrial radiation and Erb's model and creates
    sinusoidal durinal cycle to create an average day for each month

    Parameters
    ----------
    df : Pandas Dataframe
        containing with single day per month and 'global_horizontal', 'temperature' column


    Returns
    -------
    Pandas Series
        containing column 'pv' with simulated PV power output
    """

    tmp_df = df.copy()
    # Add time of day and eccentricity coefficient
    tmp_df["n"] = tmp_df.index.map(lambda x: x.timetuple().tm_yday)
    tmp_df["Eo"] = tmp_df["n"].map(ecc_corr)

    if frequency == "H" and "diffuse_fraction" not in tmp_df.columns:
        # Calculate sunset and sunrise times and write to dataframe:
        if "rise_set" not in tmp_df:
            daily_df = tmp_df.resample(rule="D").pad()
            daily_df["rise_set"] = trigon.sun_rise_set_times(
                daily_df.index, coords)
            daily_df = daily_df.reindex(
                pd.date_range(tmp_df.index[0], tmp_df.index[-1], freq="H"),
                method="ffill",
            )
            tmp_df["rise_set"] = daily_df["rise_set"]
            tmp_df["sunrise_h"] = tmp_df["rise_set"].map(
                lambda x: decimal_hours(x[0], "sunrise"))
            tmp_df["sunset_h"] = tmp_df["rise_set"].map(
                lambda x: decimal_hours(x[1], "sunset"))
        tmp_df["hour"] = tmp_df.index.hour
        tmp_df_du = tmp_df
    else:
        # Generate durinal cycle for each day:
        tmp_df_du = convert_to_durinal(tmp_df, coords, factor=24)

    # Determine hourly clearness index:
    tmp_df_kd = clearness_index_hourly(tmp_df_du, coords)
    # Calculate diffuse fraction:
    tmp_df_kd["diffuse_fraction"] = brl_model.run(
        tmp_df_kd["kt_h"], coords, tmp_df_kd["rise_set"].tolist())
    # Run PV-model
    for col in tmp_df_kd.columns:
        if col not in ["global_horizontal", "diffuse_fraction", "temperature"]:
            tmp_df_kd = tmp_df_kd.drop([col], axis=1)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        pv_h = pv_model.run_model(data=tmp_df_kd, coords=coords, **params)
    if frequency != "H":
        pv = pv_h.resample(rule="1D").sum()
        pv = pv[pv.index.isin(df.index)]
    else:
        pv = pv_h
    pv = pv[np.isfinite(pv)]
    pv.columns = ["pv"]

    return pv