Skip to content

Commit dcd202c

Browse files
committed
Add support for 'return_components'
1 parent 97a34f6 commit dcd202c

1 file changed

Lines changed: 57 additions & 21 deletions

File tree

pvlib/irradiance.py

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ def get_total_irradiance(surface_tilt, surface_azimuth,
281281
dni, ghi, dhi, dni_extra=None, airmass=None,
282282
albedo=0.25, surface_type=None,
283283
model='isotropic',
284-
model_perez='allsitescomposite1990'):
284+
model_perez='allsitescomposite1990',
285+
diffuse_components=False):
285286
r"""
286287
Determine total in-plane irradiance and its beam, sky diffuse and ground
287288
reflected components, using the specified sky diffuse irradiance model.
@@ -332,10 +333,15 @@ def get_total_irradiance(surface_tilt, surface_azimuth,
332333
``'perez-driesse'``.
333334
model_perez : str, default 'allsitescomposite1990'
334335
Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`.
336+
diffuse_components : bool, default False
337+
If `True`, returns values for the different diffuse irradiance
338+
components available from the selected model
339+
(e.g., isotropic, circumsolar, horizon brightening).
340+
If `False`, only the total diffuse irradiance is returned.
335341
336342
Returns
337343
-------
338-
total_irrad : OrderedDict or DataFrame
344+
total_irrad : Dict or DataFrame
339345
Contains keys/columns ``'poa_global', 'poa_direct', 'poa_diffuse',
340346
'poa_sky_diffuse', 'poa_ground_diffuse'``. [Wm⁻²]
341347
@@ -353,7 +359,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth,
353359
poa_sky_diffuse = get_sky_diffuse(
354360
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
355361
dni, ghi, dhi, dni_extra=dni_extra, airmass=airmass, model=model,
356-
model_perez=model_perez)
362+
model_perez=model_perez, return_components=diffuse_components)
357363

358364
poa_ground_diffuse = get_ground_diffuse(surface_tilt, ghi, albedo,
359365
surface_type)
@@ -366,7 +372,8 @@ def get_sky_diffuse(surface_tilt, surface_azimuth,
366372
solar_zenith, solar_azimuth,
367373
dni, ghi, dhi, dni_extra=None, airmass=None,
368374
model='isotropic',
369-
model_perez='allsitescomposite1990'):
375+
model_perez='allsitescomposite1990',
376+
return_components=False):
370377
r"""
371378
Determine in-plane sky diffuse irradiance component
372379
using the specified sky diffuse irradiance model.
@@ -408,11 +415,20 @@ def get_sky_diffuse(surface_tilt, surface_azimuth,
408415
``'perez-driesse'``.
409416
model_perez : str, default 'allsitescomposite1990'
410417
Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`.
418+
return_components : bool, default False
419+
If `True`, returns values for the different diffuse irradiance
420+
components available from the selected model
421+
(e.g., isotropic, circumsolar, horizon brightening).
422+
If `False`, only the total diffuse irradiance is returned.
411423
412424
Returns
413425
-------
414-
poa_sky_diffuse : numeric
415-
Sky diffuse irradiance in the plane of array. [Wm⁻²]
426+
numeric, Dict, or DataFrame
427+
Return type controlled by ``return_components`` argument.
428+
If `False`, total sky diffuse irradiance in the plane of array
429+
is returned (numeric). [Wm⁻²]
430+
If `True`, the different diffuse components are returned
431+
(Dict or DataFrame). [Wm⁻²]
416432
417433
Raises
418434
------
@@ -443,28 +459,32 @@ def get_sky_diffuse(surface_tilt, surface_azimuth,
443459
raise ValueError(f'dni_extra is required for model {model}')
444460

445461
if model == 'isotropic':
446-
sky = isotropic(surface_tilt, dhi)
462+
sky = isotropic(surface_tilt, dhi, return_components=return_components)
447463
elif model == 'klucher':
448464
sky = klucher(surface_tilt, surface_azimuth, dhi, ghi,
449-
solar_zenith, solar_azimuth)
465+
solar_zenith, solar_azimuth,
466+
return_components=return_components)
450467
elif model == 'haydavies':
451468
sky = haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
452-
solar_zenith, solar_azimuth)
469+
solar_zenith, solar_azimuth,
470+
return_components=return_components)
453471
elif model == 'reindl':
454472
sky = reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
455-
solar_zenith, solar_azimuth)
473+
solar_zenith, solar_azimuth,
474+
return_components=return_components)
456475
elif model == 'king':
457476
sky = king(surface_tilt, dhi, ghi, solar_zenith)
458477
elif model == 'perez':
459478
if airmass is None:
460479
airmass = atmosphere.get_relative_airmass(solar_zenith)
461480
sky = perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
462481
solar_zenith, solar_azimuth, airmass,
463-
model=model_perez)
482+
model=model_perez, return_components=return_components)
464483
elif model == 'perez-driesse':
465484
# perez_driesse will calculate its own airmass if needed
466485
sky = perez_driesse(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
467-
solar_zenith, solar_azimuth, airmass)
486+
solar_zenith, solar_azimuth, airmass,
487+
return_components=return_components)
468488
else:
469489
raise ValueError(f'invalid model selection {model}')
470490

@@ -488,7 +508,7 @@ def poa_components(aoi, dni, poa_sky_diffuse, poa_ground_diffuse):
488508
Direct normal irradiance, as measured from a TMY file or
489509
calculated with a clearsky model. See :term:`dni`. [Wm⁻²]
490510
491-
poa_sky_diffuse : numeric
511+
poa_sky_diffuse : numeric, Dict or DataFrame
492512
Diffuse irradiance in the plane of the modules, as
493513
calculated by a diffuse irradiance translation function. [Wm⁻²]
494514
@@ -499,7 +519,7 @@ def poa_components(aoi, dni, poa_sky_diffuse, poa_ground_diffuse):
499519
500520
Returns
501521
-------
502-
irrads : OrderedDict or DataFrame
522+
irrads : Dict or DataFrame
503523
Contains the following keys:
504524
505525
* ``poa_global`` : Total in-plane irradiance. [Wm⁻²]
@@ -508,22 +528,38 @@ def poa_components(aoi, dni, poa_sky_diffuse, poa_ground_diffuse):
508528
* ``poa_sky_diffuse`` : In-plane diffuse irradiance from sky. [Wm⁻²]
509529
* ``poa_ground_diffuse`` : In-plane diffuse irradiance from ground.
510530
[Wm⁻²]
531+
532+
If ``poa_sky_diffuse`` is a Dict or DataFrame, ``irrads`` will
533+
contain additional keys for each of the diffuse components returned by
534+
the selected diffuse irradiance model.
511535
512536
Notes
513537
------
514538
Negative beam irradiation due to AOI > 90° or AOI < 0° is set to zero.
515539
'''
516540

541+
if isinstance(poa_sky_diffuse, dict):
542+
sky_components = poa_sky_diffuse.copy()
543+
total_poa_sky_diffuse = sky_components.pop('poa_sky_diffuse')
544+
elif isinstance(poa_sky_diffuse, pd.DataFrame):
545+
sky_components = poa_sky_diffuse.to_dict(orient='series')
546+
total_poa_sky_diffuse = sky_components.pop('poa_sky_diffuse')
547+
else:
548+
sky_components = {}
549+
total_poa_sky_diffuse = poa_sky_diffuse
550+
517551
poa_direct = np.maximum(dni * np.cos(np.radians(aoi)), 0)
518-
poa_diffuse = poa_sky_diffuse + poa_ground_diffuse
552+
poa_diffuse = total_poa_sky_diffuse + poa_ground_diffuse
519553
poa_global = poa_direct + poa_diffuse
520554

521-
irrads = OrderedDict()
522-
irrads['poa_global'] = poa_global
523-
irrads['poa_direct'] = poa_direct
524-
irrads['poa_diffuse'] = poa_diffuse
525-
irrads['poa_sky_diffuse'] = poa_sky_diffuse
526-
irrads['poa_ground_diffuse'] = poa_ground_diffuse
555+
irrads = {
556+
'poa_global': poa_global,
557+
'poa_direct': poa_direct,
558+
'poa_diffuse': poa_diffuse,
559+
'poa_sky_diffuse': total_poa_sky_diffuse,
560+
'poa_ground_diffuse': poa_ground_diffuse,
561+
**sky_components
562+
}
527563

528564
if isinstance(poa_direct, pd.Series):
529565
irrads = pd.DataFrame(irrads)

0 commit comments

Comments
 (0)