예제 #1
0
def get_solar(
    latitude, longitude, start, end, DT
):  # Provides solar angle for each time step

    site_location = location.Location(latitude, longitude)

    times = pd.date_range(
        start,
        end,
        freq=(str(int(DT / 60)) + "T"),
    )

    # Get solar azimuth and zenith to pass to the transposition function
    solar_position = site_location.get_solarposition(times=times, method="ephemeris")

    solar_df = pd.DataFrame(
        {
            # "ghics": clearsky["ghi"],
            # "difcs": clearsky["dhi"],
            # "zen": solar_position["zenith"],
            "sea": np.radians(solar_position["elevation"]),
        }
    )
    solar_df.loc[solar_df["sea"] < 0, "sea"] = 0
    solar_df.index = solar_df.index.set_names(["When"])
    solar_df = solar_df.reset_index()
    return solar_df
예제 #2
0
def _calculate_poa(tmy, PV):
    """
    Input:      tmy irradiance data
    Output:     PV.poa -- plane of array

    Remember, PV GIS (C) defines the folowing:
    G(h): Global irradiance on the horizontal plane (W/m2)                        === GHI
    Gb(n): Beam/direct irradiance on a plane always normal to sun rays (W/m2)     === DNI
    Gd(h): Diffuse irradiance on the horizontal plane (W/m2)                      === DHI
    """
    # define site location for getting solar positions
    tmy.site = location.Location(tmy.lat, tmy.lon, tmy.tz)
    # Get solar azimuth and zenith to pass to the transposition function
    solar_position = tmy.site.get_solarposition(times=tmy.index)
    # Use get_total_irradiance to transpose, based on solar position
    POA_irradiance = irradiance.get_total_irradiance(
        surface_tilt=PV.tilt,
        surface_azimuth=PV.azimuth,
        dni=tmy["Gb(n)"],
        ghi=tmy["G(h)"],
        dhi=tmy["Gd(h)"],
        solar_zenith=solar_position["apparent_zenith"],
        solar_azimuth=solar_position["azimuth"],
    )
    # Return DataFrame
    PV.poa = POA_irradiance["poa_global"]
    return
예제 #3
0
def albuquerque():
    """pvlib Location for Albuquerque, NM."""
    return location.Location(35.0844,
                             -106.6504,
                             name='Albuquerque',
                             altitude=1500,
                             tx='Etc/GMT+7')
예제 #4
0
    def __init__(self, tz, lat, lon):
        # For this example, we will be using Golden, Colorado
        self.tz = tz
        self.lat = lat
        self.lon = lon

        # Create location object to store lat, lon, timezone
        self.site = location.Location(lat, lon, tz=tz)
예제 #5
0
def simulate_sun_positions_by_station(station_index, solar_position_method,
                                      days, lead_times, latitudes, longitudes):
    """
    This is the worker function of calculating sun positions at a specified station index. This function should
    be called from the parallel version of this function, `simulate_sun_positions`.

    Direct use of this function is discouraged. Please use the parallel version of this fucntion,
    `simulate_sun_positions`.

    :param station_index: A station index for simulation
    :param days: See `simulate_sun_positions`
    :param lead_times: See `simulate_sun_positions`
    :param latitudes: See `simulate_sun_positions`
    :param longitudes: See `simulate_sun_positions`
    :param solar_position_method: See `simulate_sun_positions`
    :return: A list with DNI, air mass, zenith, apparent zenith, and azimuth.
    """

    # Initialization
    num_lead_times, num_days = len(lead_times), len(days)

    dni_extra = np.zeros((num_lead_times, num_days))
    air_mass = np.zeros((num_lead_times, num_days))
    zenith = np.zeros((num_lead_times, num_days))
    apparent_zenith = np.zeros((num_lead_times, num_days))
    azimuth = np.zeros((num_lead_times, num_days))

    # Determine the current location
    current_location = location.Location(latitude=latitudes[station_index],
                                         longitude=longitudes[station_index])

    for day_index in range(num_days):
        for lead_time_index in range(num_lead_times):

            # Determine the current time
            current_posix = days[day_index] + lead_times[lead_time_index]
            current_time = pd.Timestamp(current_posix, tz="UTC", unit='s')

            # Calculate sun position
            solar_position = current_location.get_solarposition(
                current_time, method=solar_position_method, numthreads=1)

            # Calculate extraterrestrial DNI
            dni_extra[lead_time_index,
                      day_index] = irradiance.get_extra_radiation(current_time)

            # Calculate air mass
            air_mass[lead_time_index,
                     day_index] = atmosphere.get_relative_airmass(
                         solar_position["apparent_zenith"])

            # Store other keys
            zenith[lead_time_index, day_index] = solar_position["zenith"]
            apparent_zenith[lead_time_index,
                            day_index] = solar_position["apparent_zenith"]
            azimuth[lead_time_index, day_index] = solar_position["azimuth"]

    return [dni_extra, air_mass, zenith, apparent_zenith, azimuth]
예제 #6
0
    def get_poa_and_ghi_irradiance(self, df=None):
    
        # For this example, we will be using Golden, Colorado
        tz = 'UTC'
        lat = 50.33
        lon = -4.034
        # lat, lon = 39.755, -105.221

        # Create location object to store lat, lon, timezone
        site = location.Location(lat, lon, tz=tz)


        # Calculate clear-sky GHI and transpose to plane of array
        # Define a function so that we can re-use the sequence of operations with
        # different locations
        def get_irradiance(site_location, date, tilt, surface_azimuth, periods):
            # Creates one day's worth of 10 min intervals
            times = pd.date_range(date, freq='30min', periods=periods,
                                  tz=site_location.tz)
            # Generate clearsky data using the Ineichen model, which is the default
            # The get_clearsky method returns a dataframe with values for GHI, DNI,
            # and DHI
        #     print(times)
            clearsky = site_location.get_clearsky(times,model='ineichen')
            # Get solar azimuth and zenith to pass to the transposition function
            solar_position = site_location.get_solarposition(times=times)
            # Use the get_total_irradiance function to transpose the GHI to POA
            POA_irradiance = irradiance.get_total_irradiance(
                surface_tilt=tilt,
                surface_azimuth=surface_azimuth,
                dni=clearsky['dni'],
                ghi=clearsky['ghi'],
                dhi=clearsky['dhi'],
                solar_zenith=solar_position['apparent_zenith'],
                solar_azimuth=solar_position['azimuth'])

            # Return DataFrame with only GHI and POA
            return pd.DataFrame({'GHI': clearsky['ghi'],
                                 'POA': POA_irradiance['poa_global']})
        if df is None:
            
            df_solar_irr = get_irradiance(site, '{}-{}-{}'.format(self.df.index.date[0].year, self.df.index.date[0].month, 
                                                                  self.df.index.date[0].day), 90, 180, len(self.df))
    #         new_df = df.copy()
            self.df['GHI'] = df_solar_irr['GHI'].values
            self.df['POA'] = df_solar_irr['POA'].values

            return self.df
        else:
            df_solar_irr = get_irradiance(site, '{}-{}-{}'.format(df.index.date[0].year, df.index.date[0].month, 
                                                                  df.index.date[0].day), 90, 180, len(df))
    #         new_df = df.copy()
            df['GHI'] = df_solar_irr['GHI'].values
            df['POA'] = df_solar_irr['POA'].values
            return df
예제 #7
0
 def setup(self):
     self.times = pd.date_range(start='20180601', freq='1min',
                                periods=14400)
     self.days = pd.date_range(start='20180601', freq='d', periods=30)
     self.location = location.Location(40, -80)
     self.solar_position = self.location.get_solarposition(self.times)
     self.clearsky_irradiance = self.location.get_clearsky(self.times)
     self.tilt = 20
     self.azimuth = 180
     self.aoi = irradiance.aoi(self.tilt, self.azimuth,
                               self.solar_position.apparent_zenith,
                               self.solar_position.azimuth)
예제 #8
0
def bifacial(PV_instance, tmy, return_model=False):

    PV = PV_instance

    # get weather in correct format
    weather = PVlibweather(tmy)
    # define site location for getting solar positions
    tmy.site = location.Location(tmy.lat, tmy.lon, tmy.tz)
    # Get solar azimuth and zenith to pass to the transposition function
    sun = tmy.site.get_solarposition(times=tmy.index)
    # utility dataframe to supply arguments in correct dimensions
    setup = pd.DataFrame(index=tmy.index)
    setup["azimuth"] = 90
    setup["tilt"] = 90
    setup["axis"] = 0

    poa_front, poa_back, front, back = pvlib.bifacial.pvfactors_timeseries(
        solar_azimuth=sun.azimuth,
        solar_zenith=sun.zenith,
        surface_azimuth=setup.azimuth,
        surface_tilt=setup.tilt,
        axis_azimuth=setup.axis,
        timestamps=tmy.index,
        dni=weather.dni,
        dhi=weather.dhi,
        gcr=0.55,
        pvrow_height=2,
        pvrow_width=4,
        albedo=0.23,
        n_pvrows=3,
        index_observed_pvrow=1,
        rho_front_pvrow=0.03,
        rho_back_pvrow=0.05,
        horizon_band_angle=15.0,
    )

    front.index, back.index = PV.state.index, PV.state.index

    front.fillna(0, inplace=True)
    back.fillna(0, inplace=True)
    effective = front + back * PV.bifacial_factor
    poa = poa_front
    bifacial_irradiance = pd.DataFrame(index=PV.state.index)
    bifacial_irradiance["effective_irradiance"] = pd.Series(
        effective, index=PV.state.index)
    bifacial_irradiance["poa_global"] = pd.Series(poa, index=PV.state.index)
    bifacial_irradiance["wind_speed"] = pd.Series(tmy["WS"].values,
                                                  index=PV.state.index)
    bifacial_irradiance["temp_air"] = pd.Series(tmy["T"].values,
                                                index=PV.state.index)

    return bifacial_irradiance
예제 #9
0
def test_module_temperature():
    """Module temperature is correlated with GHI."""
    albuquerque = location.Location(35.0844,
                                    -106.6504,
                                    altitude=5312,
                                    tz='MST')
    times = pd.date_range(start='01/01/2020',
                          end='03/01/2020',
                          freq='H',
                          tz='MST')
    clearsky = albuquerque.get_clearsky(times, model='simplified_solis')
    assert weather.module_temperature_check(clearsky['ghi'] * 0.6,
                                            clearsky['ghi'])
    assert not weather.module_temperature_check(clearsky['ghi'] *
                                                (-0.6), clearsky['ghi'])
예제 #10
0
def test_orientation_fit_pvwatts_missing_data(naive_times):
    tilt = 30
    azimuth = 100
    system_location = location.Location(35, -106)
    local_time = naive_times.tz_localize('MST')
    clearsky = system_location.get_clearsky(local_time,
                                            model='simplified_solis')
    clearsky.loc['3/1/2020':'3/15/2020'] = np.nan
    solar_position = system_location.get_solarposition(clearsky.index)
    solar_position.loc['3/1/2020':'3/15/2020'] = np.nan
    poa = irradiance.get_total_irradiance(tilt, azimuth,
                                          solar_position['zenith'],
                                          solar_position['azimuth'],
                                          **clearsky)
    temp_cell = pvlib.temperature.sapm_cell(
        poa['poa_global'], 25, 0,
        **pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']
        ['open_rack_glass_glass'])
    pdc = pvsystem.pvwatts_dc(poa['poa_global'], temp_cell, 100, -0.002)
    pac = pvsystem.inverter.pvwatts(pdc, 120)
    solar_position.dropna(inplace=True)
    with pytest.raises(ValueError,
                       match=".* must not contain undefined values"):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            **clearsky)
    pac.dropna(inplace=True)
    with pytest.raises(ValueError,
                       match=".* must not contain undefined values"):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            **clearsky)
    clearsky.dropna(inplace=True)
    tilt_out, azimuth_out, rsquared = system.infer_orientation_fit_pvwatts(
        pac,
        solar_zenith=solar_position['zenith'],
        solar_azimuth=solar_position['azimuth'],
        **clearsky)
    assert rsquared > 0.9
    assert tilt_out == pytest.approx(tilt, abs=10)
    assert azimuth_out == pytest.approx(azimuth, abs=10)
예제 #11
0
# array using :py:func:`pvlib.bifacial.pvfactors.pvfactors_timeseries`.

import pandas as pd
from pvlib import location
from pvlib.bifacial.pvfactors import pvfactors_timeseries
import matplotlib.pyplot as plt
import warnings

# supressing shapely warnings that occur on import of pvfactors
warnings.filterwarnings(action='ignore', module='pvfactors')

# %%
# First, generate the usual modeling inputs:

times = pd.date_range('2021-06-21', '2021-06-22', freq='1T', tz='Etc/GMT+5')
loc = location.Location(latitude=40, longitude=-80, tz=times.tz)
sp = loc.get_solarposition(times)
cs = loc.get_clearsky(times)

# example array geometry
pvrow_height = 1
pvrow_width = 4
pitch = 10
gcr = pvrow_width / pitch
axis_azimuth = 180
albedo = 0.2

# %%
# Now the trick: since pvfactors only wants to model single-axis tracking
# arrays, we have to pretend our fixed tilt array is a single-axis tracking
# array that never rotates.  In that case, the "axis of rotation" is
예제 #12
0
        azimuth_subset = solar_azimuth.resample('15min').first()

        tracking_data_15min = tracking.singleaxis(
            zenith_subset, azimuth_subset, self.axis_tilt, self.axis_azimuth,
            self.max_angle, self.backtrack, self.gcr, self.cross_axis_tilt)
        # propagate the 15-minute positions to 1-minute stair-stepped values:
        tracking_data_1min = tracking_data_15min.reindex(solar_zenith.index,
                                                         method='ffill')
        return tracking_data_1min


# %%
# Let's take a look at the tracker rotation curve it produces:

times = pd.date_range('2019-06-01', '2019-06-02', freq='1min', tz='US/Eastern')
loc = location.Location(40, -80)
solpos = loc.get_solarposition(times)
mount = DiscontinuousTrackerMount(axis_azimuth=180, gcr=0.4)
tracker_data = mount.get_orientation(solpos.apparent_zenith, solpos.azimuth)
tracker_data['tracker_theta'].plot()
plt.ylabel('Tracker Rotation [degree]')
plt.show()

# %%
# With our custom tracking logic defined, we can create the corresponding
# Array and PVSystem, and then run a ModelChain as usual:

module_parameters = {'pdc0': 1, 'gamma_pdc': -0.004, 'b': 0.05}
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
array = pvsystem.Array(mount=mount,
                       module_parameters=module_parameters,
예제 #13
0
def albuquerque():
    return location.Location(35, -106, elevation=2000, tz='MST')
예제 #14
0
def test_orientation_fit_pvwatts_temp_wind_as_series(naive_times):
    tilt = 30
    azimuth = 100
    system_location = location.Location(35, -106)
    local_time = naive_times.tz_localize('MST')
    clearsky = system_location.get_clearsky(local_time,
                                            model='simplified_solis')
    solar_position = system_location.get_solarposition(clearsky.index)
    poa = irradiance.get_total_irradiance(tilt, azimuth,
                                          solar_position['zenith'],
                                          solar_position['azimuth'],
                                          **clearsky)
    temp_cell = pvlib.temperature.sapm_cell(
        poa['poa_global'], 25, 1,
        **pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']
        ['open_rack_glass_glass'])
    temperature = pd.Series(25, index=clearsky.index)
    wind_speed = pd.Series(1, index=clearsky.index)
    temperature_missing = temperature.copy()
    temperature_missing.loc['4/5/2020':'4/10/2020'] = np.nan
    wind_speed_missing = wind_speed.copy()
    wind_speed_missing.loc['5/5/2020':'5/15/2020'] = np.nan
    pdc = pvsystem.pvwatts_dc(poa['poa_global'], temp_cell, 100, -0.002)
    pac = pvsystem.inverter.pvwatts(pdc, 120)
    with pytest.raises(ValueError,
                       match=".* must not contain undefined values"):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            temperature=temperature_missing,
            wind_speed=wind_speed_missing,
            **clearsky)
    with pytest.raises(ValueError,
                       match="temperature must not contain undefined values"):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            temperature=temperature_missing,
            wind_speed=wind_speed,
            **clearsky)
    with pytest.raises(ValueError,
                       match="wind_speed must not contain undefined values"):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            temperature=temperature,
            wind_speed=wind_speed_missing,
            **clearsky)
    # ValueError if indices don't match
    with pytest.raises(ValueError):
        system.infer_orientation_fit_pvwatts(
            pac,
            solar_zenith=solar_position['zenith'],
            solar_azimuth=solar_position['azimuth'],
            temperature=temperature_missing.dropna(),
            wind_speed=wind_speed_missing.dropna(),
            **clearsky)
    tilt_out, azimuth_out, rsquared = system.infer_orientation_fit_pvwatts(
        pac,
        solar_zenith=solar_position['zenith'],
        solar_azimuth=solar_position['azimuth'],
        **clearsky)
    assert rsquared > 0.9
    assert tilt_out == pytest.approx(tilt, abs=10)
    assert azimuth_out == pytest.approx(azimuth, abs=10)
예제 #15
0
def system_location(request):
    """Location of the system."""
    return location.Location(request.param[0],
                             request.param[1],
                             tz=request.param[2])
예제 #16
0
def irradiance_summer_winter(lat, lon, tz):
    site = location.Location(lat, lon, tz=tz)

    # Calculate clear-sky GHI and transpose to plane of array
    # Define a function so that we can re-use the sequence of operations with
    # different locations
    def get_irradiance(site_location, date, tilt, surface_azimuth):
        # Creates one day's worth of hour intervals
        times = pd.date_range(date, freq='h', periods=24, tz=site_location.tz)
        # Generate clearsky data using the Ineichen model, which is the default
        # The get_clearsky method returns a dataframe with values for GHI, DNI,
        # and DHI
        clearsky = site_location.get_clearsky(times)
        # Get solar azimuth and zenith to pass to the transposition function
        solar_position = site_location.get_solarposition(times=times)
        # Use the get_total_irradiance function to transpose the GHI to POA
        POA_irradiance = irradiance.get_total_irradiance(
            surface_tilt=tilt,
            surface_azimuth=surface_azimuth,
            dni=clearsky['dni'],
            ghi=clearsky['ghi'],
            dhi=clearsky['dhi'],
            solar_zenith=solar_position['apparent_zenith'],
            solar_azimuth=solar_position['azimuth'])
        # Return DataFrame with only GHI and POA
        return pd.DataFrame({
            'GHI': clearsky['ghi'],
            'POA': POA_irradiance['poa_global']
        })

    # Get irradiance data for summer and winter solstice, assuming 25 degree tilt
    # and a south facing array

    if lon > 0:
        winter = '12-20-2020'
        summer = '06-21-2020'
    else:
        summer = '12-20-2020'
        winter = '06-21-2020'
    tilt = abs(lat)
    if lon > 0:
        face = 180

    summer_irradiance = get_irradiance(site, summer, tilt, 0)
    winter_irradiance = get_irradiance(site, winter, tilt, 0)

    # Convert Dataframe Indexes to Hour:Minute format to make plotting easier
    summer_irradiance.index = summer_irradiance.index.strftime("%H:%M")
    winter_irradiance.index = winter_irradiance.index.strftime("%H:%M")

    # Plot GHI vs. POA for winter and summer
    fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
    summer_irradiance['GHI'].plot(ax=ax1, label='GHI')
    summer_irradiance['POA'].plot(ax=ax1, label='POA')
    winter_irradiance['GHI'].plot(ax=ax2, label='GHI')
    winter_irradiance['POA'].plot(ax=ax2, label='POA')
    ax1.set_xlabel('Time of day (Summer)')
    ax2.set_xlabel('Time of day (Winter)')
    ax1.set_ylabel('Irradiance ($W/m^2$)')
    ax1.legend()
    ax2.legend()
    #plt.show()
    return fig
# :py:meth:`pvlib.location.Location.get_clearsky` method to generate clearsky
# GHI data as well as how to use the
# :py:meth:`pvlib.irradiance.get_total_irradiance` function to transpose
# GHI data to Plane of Array (POA) irradiance.

from pvlib import location
from pvlib import irradiance
import pandas as pd
from matplotlib import pyplot as plt

# For this example, we will be using Golden, Colorado
tz = 'MST'
lat, lon = 39.755, -105.221

# Create location object to store lat, lon, timezone
site = location.Location(lat, lon, tz=tz)


# Calculate clear-sky GHI and transpose to plane of array
# Define a function so that we can re-use the sequence of operations with
# different locations
def get_irradiance(site_location, date, tilt, surface_azimuth):
    # Creates one day's worth of 10 min intervals
    times = pd.date_range(date, freq='10min', periods=6*24,
                          tz=site_location.tz)
    # Generate clearsky data using the Ineichen model, which is the default
    # The get_clearsky method returns a dataframe with values for GHI, DNI,
    # and DHI
    clearsky = site_location.get_clearsky(times)
    # Get solar azimuth and zenith to pass to the transposition function
    solar_position = site_location.get_solarposition(times=times)
예제 #18
0
from pvlib import irradiance
from pvlib import location
from pvlib.pvsystem import PVSystem
#from pvlib.location import Location
from pvlib.modelchain import ModelChain
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
import weatherData

latitude, longitude, tz = 63.42024, 10.40122, 'Europe/Oslo'  # specify location
start = pd.Timestamp(datetime.date.today(), tz=tz)
end = start + pd.Timedelta(days=1)
irrad_vars = ['ghi', 'dni', 'dhi']

# Create location object to store lat, lon, timezone
#location = Location(latitude=63.42024, longitude=10.40122) # Bredd/lengde-grad for Trondheim
site = location.Location(latitude, longitude, tz=tz)

temperature_model_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm'][
    'open_rack_glass_glass']
# Bestemmer hvilke moduler og invertere vi ønsker å modelere.
sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
cec_inverters = pvlib.pvsystem.retrieve_sam('cecinverter')
sandia_module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
cec_inverter = cec_inverters['ABB__MICRO_0_25_I_OUTD_US_208__208V_']


# Calculate clear-sky GHI and transpose to plane of array
def get_irradiance(site_location, date, tilt, surface_azimuth):
    # Creates one day's worth of 10 min intervals
    times = pd.date_range(date,
                          freq='10min',
예제 #19
0
gcr = 0.35
max_angle = 60
pvrow_height = 3
pvrow_width = 4
albedo = 0.2
bifaciality = 0.75

# load temperature parameters and module/inverter specifications
temp_model_parameters = PARAMS['sapm']['open_rack_glass_glass']
cec_modules = pvsystem.retrieve_sam('CECMod')
cec_module = cec_modules['Trina_Solar_TSM_300DEG5C_07_II_']
cec_inverters = pvsystem.retrieve_sam('cecinverter')
cec_inverter = cec_inverters['ABB__MICRO_0_25_I_OUTD_US_208__208V_']

# create a location for site, and get solar position and clearsky data
site_location = location.Location(lat, lon, tz=tz, name='Greensboro, NC')
solar_position = site_location.get_solarposition(times)
cs = site_location.get_clearsky(times)

# load solar position and tracker orientation for use in pvsystem object
sat_mount = pvsystem.SingleAxisTrackerMount(axis_tilt=axis_tilt,
                                            axis_azimuth=axis_azimuth,
                                            max_angle=max_angle,
                                            backtrack=True,
                                            gcr=gcr)

# created for use in pvfactors timeseries
orientation = sat_mount.get_orientation(solar_position['apparent_zenith'],
                                        solar_position['azimuth'])

# get rear and front side irradiance from pvfactors transposition engine
예제 #20
0
def deviation(start_time, end_time, location_coor, input_solar_file, x_name):
    try:
        obs = pd.read_csv(input_solar_file)
    except:
        raise ValueError('Invalid input solar file name')
    obs = obs.set_index(pd.DatetimeIndex(pd.to_datetime(obs['datetime'])))
    obs = obs.iloc[:, 1:]
    if start_time == None:
        start_time = str(obs.index[0])
    if end_time == None:
        end_time = str(obs.index[-1])
    start_time = pd.to_datetime(start_time + ' 00:00:00')
    end_time = pd.to_datetime(end_time + ' 00:00:00')
    if (obs.index[0] > start_time) or (obs.index[-1] < end_time):
        raise ValueError('Invalid start or end date. The input file has date range {} to {}'.format(
            obs.index[0], obs.index[-1]))
    obs = obs[(obs.index >= start_time)
              & (obs.index < end_time)]
    cap = max(obs[x_name])
    times = pd.date_range(start=start_time,
                          end=end_time, freq='60min', closed='left')
    location_coor = list(location_coor[0].split())
    for i in range(len(location_coor)):
        location_coor[i] = int(location_coor[i])
    length = int(len(location_coor))
    POA = pd.DataFrame()
    for i in range(int(length/2)):
        lat = location_coor[2*i]
        lon = location_coor[2*i+1]
        site = location.Location(lat, lon)
        POA_single = get_irradiance(site, 15, 180, times)
        POA = pd.concat([POA, POA_single], axis=1)
        POA = POA.max(axis=1)
        POA = POA.to_frame()
        POA.rename(columns={POA.columns[0]: "poa_global"}, inplace=True)
        n = POA.size

    # calculate csi
    norm_max = POA.max()
    csi = POA.div(norm_max)
    max_csi_d = []
    for i in range(int(n/24)):
        max_csi_d.append(float(csi.iloc[i*24:i*24+24].max().values))
        csi_list = csi['poa_global'].tolist()
        csi_list = flatten(csi_list)

    # calculate p
    max_p_d = []
    forecast = obs.iloc[:, 0]
    forecast = forecast.to_frame()
    actual = obs.iloc[:, 1]
    actual_list = actual.tolist()
    actual = actual.to_frame()
    for i in range(int(n/24)):
        max_p_d.append(float(actual.iloc[i*24:i*24+24].max()))

    # calculate G
    G = div(max_p_d, max_csi_d)
    # make G non-decreasing
    for i in range(len(G)-1):
        if G[i+1] < G[i]:
            G[i+1] = G[i]

    # calculate T
    T = []
    interm = div(actual_list, csi_list)
    for i in range(int(n/24)):
        T.append(max(interm[i*24: i*24+24])/G[i])
    upper = []
    for i in range(int(n/24)):
        for j in range(24):
            upper.append(G[i]*min(max_csi_d[i], T[i]*csi_list[i*24+j]))
    upper_df = pd.DataFrame(upper, index=times, columns=['upper bound'])
    upper_df.index.name = 'datetimes'
    forecast_div = upper_df.values-forecast.values
    deviation_df = pd.DataFrame(
        forecast_div, index=times, columns=['forecasts'])
    deviation_df['actuals'] = upper_df.values-actual.values
    deviation_df.to_csv('deviation.csv')  # input for mape_maker, needed
    return upper_df, cap