atlite icon indicating copy to clipboard operation
atlite copied to clipboard

Cutout - Access to irradiation data

Open Tasqu opened this issue 4 years ago • 4 comments

Change proposed in this Pull Request

  1. Added a new optional keyword irradiance='total' to TiltedIrradiance() to determine whether to return total, direct, diffuse, or ground irradiation. Default assumption is total to preserve the original functionality.
  2. Added convert_irradiation() and irradiation() methods to the Cutout class to access the raw irradiance data calculated via TiltedIrradiance().
  3. Also added a new example for demonstrating a use case for the feature.

Description

pv/irratiation.py TiltedIrradiation()

Added a new optional keyword irradiation="total" to define what irradiation quantity should be returned. Previously, TiltedIrradiation() only returned the total irradiation, but for my purposes, I needed access to direct and diffuse irradiation on a tilted surface separately. The method defaults to irradiation="total" in order to minimise the impact of this change on the rest of atlite.

convert.py convert_irradiation() and irradiation()

Added two new methods for accessing the raw irradiation data, convert_irradiation() and irradiation(). These are basically just reduced versions of the convert_pv() and pv() methods, where we skip the final conversion from solar irradiation to PV generation.

cutout.py irradiation

Added the irradiation() method to the Cutout class in order to access the raw irradiation data.

examples/finnish_building_stock_weather_aggregation.ipynb

Added a new example to demonstrate using the added features.

examples/finnish_building_stock_weather_aggregation.ipynb.license

License file for the new example, GPL-3.0-or-later

doc/examples/finnish_building_stock_weather_aggregation.nblink

nblink file for the new example.

doc/index.rst

Tried adding the new example into the documentation, but I couldn't figure out how to build the documentation locally to test this.

Motivation and Context

NOTE! I'm more or less still a beginner when it comes to Python programming, so my code is potentially not the cleanest, nor do I understand anything about generating documentation. For that, I apologise.

I'm working on modelling the heat demand of the Finnish building stock, its potential flexibility, as well as its value in large-scale energy system context. For this reason, I need to be able to calculate historical weather time series over large geographical areas, weighted based on where the majority of the heated volume of the building stock is located. We've used in-house Python codes for these kinds of things previously, but those have fell into disrepair after the original developers have moved on.

Seeing that atlite was already capable of doing all the calculations I need, I decided it would be easier to tweak atlite, than to try and learn and repair our old in-house codes. However, the current atlite master doesn't actually contain methods for accessing the tilted solar irradiation directly, as it is only used for PV and solar thermal conversion. Thus, I added the necessary methods myself.

How Has This Been Tested?

So far, mostly just using the examples. The new one works as intended, and I don't think I broke any of the old ones.

Also run the pytest as suggested by the checklist, and nothing alarming seemed to come up. (Although, I'm still a beginner with Python so I'm not sure I would necessarily recognise potential issues)

Type of change

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • [x] I tested my contribution locally and it seems to work fine.
  • [x] I locally ran pytest inside the repository and no unexpected problems came up.
  • [x] I have adjusted the docstrings in the code appropriately.
  • [x] I have documented the effects of my code changes in the documentation doc/. (I tried adding the new example to the documentation, but don't know how to test building the documentation locally.)
  • [ ] I have added newly introduced dependencies to environment.yaml file. (no new dependencies)
  • [ ] I have added a note to release notes doc/release_notes.rst. (RELEASE_NOTES.rst or doc/release_notes.rst? The doc version seems a bit weird for editing...)
  • [x] I have used pre-commit run --all to lint/format/check my contribution

Tasqu avatar Dec 09 '21 09:12 Tasqu

Hi @Tasqu !

Thanks for your PR. I'll have a look at it later this week or next week.

euronion avatar Dec 13 '21 09:12 euronion

@euronion I've been a bit busy lately, so I don't know when I'll have the time to address your comments above. Hopefully within a few weeks, but I can't make any promises...

Still, thanks for going through my pull request, and for the thorough feedback!

Tasqu avatar Jan 14 '22 05:01 Tasqu

Great. 👍 No need for promises, As the old saying goes: “Your contributions are never late, nor are they early, they arrive precisely when you meant them to."

euronion avatar Jan 14 '22 07:01 euronion

@euronion Ok, I think I've addressed all of your previous comments. I also revised the example so that it doesn't display any unnecessary intermediate output, and included the outputs of interest into the notebook.

Tasqu avatar Mar 08 '22 05:03 Tasqu

@FabianHofmann can you clarify which part of the example code you're referring to? In the beginning, I clip the raw European population density raster with

finland_population_density = (
    population_density.rio.clip(finland_3035.geometry, from_disk=True)
    .rio.reproject(cutout.crs, from_disk=True)
    .squeeze()
)

and I couldn't figure out a way to do the clipping as part of the .rio.reproject method. However, your tip helped me clean up the resampling of the raster quite a bit via

layout = finland_population_density.rio.reproject(
    cutout.crs,
    shape=cutout.shape,
    transform=cutout.transform,
    resampling=5,
    from_disk=True
)

instead of the coarsen method trickery I had before. Thanks a bunch! This actually helps me improve some of my other code as well.

Tasqu avatar May 04 '23 08:05 Tasqu

Hey @Tasqu! Good to hear. It seems that the clipping has to be done either way before the reproject. So you could probably do

layout = (
    population_density.rio.clip(finland_3035.geometry, from_disk=True)
    .rio.reproject(cutout.crs, shape=cutout.shape, transform=cutout.transform, resampling=5, from_disk=True)
    .squeeze()
)

FabianHofmann avatar May 04 '23 08:05 FabianHofmann

Ok, I revised the example to be a bit more dense (and fixed a few typos). I also went through the pull request checklist again, but it seems that pytest doesn't pass at the moment (seems like master is suffering from the same issue?)

Let me know if there's still some stuff you need improved.

Tasqu avatar May 04 '23 10:05 Tasqu

@euronion you have to approve that you are happy with your requested changes now

FabianHofmann avatar May 04 '23 11:05 FabianHofmann

@Tasqu would you be fine if we squash this before merging?

FabianHofmann avatar May 08 '23 08:05 FabianHofmann

@FabianHofmann I have no objections, it's your codebase after all 😉

Tasqu avatar May 09 '23 05:05 Tasqu

great thanks @Tasqu

FabianHofmann avatar May 09 '23 09:05 FabianHofmann