# Compute angle of incidence of sun on POA.
aoi_deg = pvlib.irradiance.aoi(
array["surface_tilt_deg"],
array["surface_azimuth_deg"],
weather["apparent_zenith"],
weather["azimuth"],
)
# Compute direct component on POA.
poa_components = pandas.DataFrame(
data={"direct": numpy.maximum(weather["dni"] * numpy.cos(numpy.radians(aoi_deg)), 0)},
index=weather.index
)
# Compute sky-diffuse components on POA using Perez allsitescomposite1990.
poa_components_perez = pvlib.irradiance.perez(
array["surface_tilt_deg"],
array["surface_azimuth_deg"],
weather["dhi"],
weather["dni"],
pvlib.irradiance.get_extra_radiation(weather.index),
weather["apparent_zenith"],
weather["azimuth"],
airmass=pvlib.atmosphere.get_relative_airmass(weather["apparent_zenith"]),
model="allsitescomposite1990", # Cf. albuquerque1988
return_components=True,
)
poa_components["circumsolar"] = poa_components_perez["circumsolar"]
poa_components["isotropic"] = poa_components_perez["isotropic"]
poa_components["horizon"] = poa_components_perez["horizon"]
# Compute ground-diffuse component on POA.
poa_components["ground_diffuse"] = pvlib.irradiance.get_ground_diffuse(
array["surface_tilt_deg"],
weather["ghi"],
albedo=array["albedo"],
)
# Compute total POA irradiance.
poa_components["total"] = numpy.sum(poa_components.to_numpy(), axis=1)
# Compute IAMs for diffuse components.
# pvlib.iam.marion_diffuse cannot make use of our custom fit IAM function,
# so instead use lower level pvlib.iam.marion_integrate for each component.
diffuse_iam = {}
for region in ["sky", "horizon", "ground"]:
diffuse_iam[region] = pvlib.iam.marion_integrate(
lambda angle_deg: iam(angle_deg=angle_deg), array["surface_tilt_deg"], region
)
# Compute IAM-corrected effective POA irradiance.
poa_components["total_eff"] = iam(angle_deg=aoi_deg) * (
poa_components["direct"] + poa_components["circumsolar"]) + \
diffuse_iam["sky"] * poa_components["isotropic"] + \
diffuse_iam["horizon"] * poa_components["horizon"] + \
diffuse_iam["ground"] * poa_components["ground_diffuse"]