Skip to content

Adapts irradiance.isotropic to return_components framework. #2527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ramaroesilva
Copy link
Contributor

@ramaroesilva ramaroesilva commented Aug 3, 2025

@ramaroesilva
Copy link
Contributor Author

For now, I only updated irradiance.isotropic as a testbed for the proposed changes.

Made use of the content from perez and haydaviesdocstrings, which were not fully consistent. Also, added the poa_ prefix to the outputs as suggested by @markcampanelli here

If this seems good to everyone, I can replicate this for all functions (adding the return_components and making documentation more consistent across fuctions, whenever each is needed).

@RDaxini RDaxini added this to the v0.13.1 milestone Aug 4, 2025
Copy link
Member

@kandersolar kandersolar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ramaroesilva! I agree it makes sense to trial it on one function first. Let's wait to do the others until #2529 has some more discussion.

In the meantime, some minor comments below.


return sky_diffuse
if return_components:
diffuse_components = OrderedDict()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor note: no need to use OrderedDict in new code (#1684)

@@ -613,10 +613,23 @@ def isotropic(surface_tilt, dhi):
dhi : numeric
Diffuse horizontal irradiance. [Wm⁻²] DHI must be >=0.
return_components : bool, default False
Flag used to decide whether to return the calculated diffuse components
or not. If `False`, ``sky_diffuse`` is returned. If `True`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
or not. If `False`, ``sky_diffuse`` is returned. If `True`,
or not. If `False`, ``poa_sky_diffuse`` is returned. If `True`,

Assuming this is in reference to the names in the Returns section

Comment on lines 629 to 633
* sky_diffuse: Total sky diffuse
* isotropic
* circumsolar
* horizon
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update with poa_ prefix

@ramaroesilva
Copy link
Contributor Author

Once more people give feedback on the documentation structuring of this example, I will continue developing the other transposition functions taking into account the OrderedDict comment. All poa_ related changes will move to a separate PR.

diffuse_components['poa_horizon'] = 0

return diffuse_components
else:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to return both poa_sky_diffuse and diffuse_components, if return_componets is True.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me. This "one or the other" is what is implemented in perez at the moment.

For clarity, do you mean returning two dictionaries, which makes the number of outputs depend on return_components, or having still one dictionary buth with an additional sky_diffuse key?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking a tuple with two dicts, when return_components is True.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwhanse I just noticed that in my latest commit I included in the diffuse_components dict the sky_diffuse as one of the keys. Would this - having a single-dict with components and their sum - make sense?

If instead we have two dictionaries as originally proposed, the one having the sky_diffuse will have a single key... How would we call the variable and the key without being repetitive? total_diffuse["sky"]?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I misspoke. Return a tuple (sky_diffuse, components) where sky_diffuse is the current numeric (Series, array, float) and components is a dict.

Copy link
Member

@cwhanse cwhanse Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edited: returning a tuple requires the user to change from

sky_diffuse = isotropic(...)

to

sky_diffuse, _ = isotropic(...)

I was (wrongly) thinking that only the first element of the tuple would be assigned to sky_diffuse. Not thinking clearly.

So now I'm not so sure that returning a tuple is a good idea. Still, it seems better than requiring the user to change to

out = isotropic(...)
sky_diffuse = out['sky_diffuse']

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying and thinking things through.

Going back to the start:

I would prefer to return both poa_sky_diffuse and diffuse_components, if return_componets is True.

I just remembered that in my latest commit the sky_diffuse is included within diffuse_components, following the workflow used in perez and haydavies. So what we are discussing here is in fact if we should change the current modus operandi of transposition models with return_components.

While what you propose is v0.13.1-friendly for the models not yet returning return_components, it would break previous code for those that already do. Having this said, I would suggest moving this specific topic to a separate issue and raise some discussion aiming for v0.14.

What do you think? If agreed, can you can raise a new issue like @kandersolar did in #2529?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just remembered that in my latest commit the sky_diffuse is included within diffuse_components, following the workflow used in perez and haydavies. So what we are discussing here is in fact if we should change the current modus operandi of transposition models with return_components.

All the irradiance component sets I looked at include both components and sums of components. I think the cleanest way would be (would have been) to include only the lowest level and leave the summation up to the user.

Comment on lines +669 to +672
if isinstance(poa_sky_diffuse, pd.Series):
# follows `perez` worfklow
# shouldn't it include an argument `index=dhi.index`?
diffuse_components = pd.DataFrame(diffuse_components)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any comments about my question here? This code is used in perez.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, should preserve the index from dhi

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would adding this index bit to the diffuse-component-including perez and haydavies functions be considered a breaking change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's a breaking change. pvlib strives that a function returns the same data type as the inputs. That's one reason we test functions with different input types. If those functions are returning e.g. Array for Series input, I'd regard that as a bug that needs fixing.

In perez the index wasn't explicitly set because the upstream calculations resulted in sky_diffuse being a Series. I think it's better to be explicit, just in case the calculation uses some numpy function that casts Series to Array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider allowing return_components in all transposition model functions
5 participants