google-deepmind / graphcast

Apache License 2.0
4.36k stars 537 forks source link

How to calculate toa_incident_solar_radiation? #42

Closed ihecha closed 6 months ago

ihecha commented 6 months ago

I look at the sample code. If you want to predict future weather, you also need to calculate the variable toa_incident_solar_radiation. But how to calculate this variable? I use pysolar, but I can’t get an approximate value.

abhinavyesss commented 6 months ago
#!/usr/bin/env python3
#pyright: reportMissingImports=false

from pysolar.radiation import get_radiation_direct
from pysolar.solar import get_altitude

from constants.constants import Constants
from util.util import UtilityFunctions as uti

class SolarFunctions:

    @classmethod
    def getSolarRadiation(cls, longitude, latitude, dt):

        altitude_degrees = get_altitude(latitude, longitude, uti.addTimezone(dt))
        solar_radiation = get_radiation_direct(dt, altitude_degrees) if altitude_degrees > 0 else 0

        return solar_radiation * Constants.WATTS_TO_JOULES

Constants.WATTS_TO_JOULES = 3600. latitude, longitude are the coordinates. dt is the datetime.datetime object, make sure to add the timezone.

ihecha commented 6 months ago
#!/usr/bin/env python3
#pyright: reportMissingImports=false

from pysolar.radiation import get_radiation_direct
from pysolar.solar import get_altitude

from constants.constants import Constants
from util.util import UtilityFunctions as uti

class SolarFunctions:

    @classmethod
    def getSolarRadiation(cls, longitude, latitude, dt):

        altitude_degrees = get_altitude(latitude, longitude, uti.addTimezone(dt))
        solar_radiation = get_radiation_direct(dt, altitude_degrees) if altitude_degrees > 0 else 0

        return solar_radiation * Constants.WATTS_TO_JOULES

Constants.WATTS_TO_JOULES = 3600. latitude, longitude are the coordinates. dt is the datetime.datetime object, make sure to add the timezone.

I used the same method as you, but it seems to be wrong. The calculated results deviate greatly from the EAR5 data. They seem to have used a more complex algorithm.

abhinavyesss commented 6 months ago

Yeah ERA5 data is calculated differently and pysolar values could vary from it, however the Deepmind team has mentioned using pysolar to get radiation values for dates ERA5 data is not present. So, not much alternative.

lvqy12 commented 6 months ago

Yeah ERA5 data is calculated differently and pysolar values could vary from it, however the Deepmind team has mentioned using pysolar to get radiation values for dates ERA5 data is not present. So, not much alternative.

Thanks for giving the code. It did not work without util.util. I try to to install util with code 'pip install util', but fail to get a right version. Can you help?

abhinavyesss commented 6 months ago

Thanks for giving the code. It did not work without util.util. I try to to install util with code 'pip install util', but fail to get a right version. Can you help?

I am sorry, util.util is the code in my system, not an external package. I have basically written a function to add a timezone to the datetime.datetime object.

@classmethod
def toDatetime(cls, dt) -> datetime.datetime:

    if isinstance(dt, datetime.date) and isinstance(dt, datetime.datetime):

        return dt

    elif isinstance(dt, datetime.date) and not isinstance(dt, datetime.datetime):

        return datetime.datetime.combine(dt, datetime.datetime.min.time())

    elif isinstance(dt, str):

        if 'T' in dt:
            return isodate.parse_datetime(dt)
        else:
            return datetime.datetime.combine(isodate.parse_date(dt), datetime.datetime.min.time())

@classmethod
def addTimezone(cls, dt, tz = pytz.UTC) -> datetime.datetime:

    dt = cls.toDatetime(dt)
    if dt.tzinfo == None:
        return pytz.UTC.localize(dt).astimezone(tz)
    else:
        return dt.astimezone(tz)
voctav commented 6 months ago

A new library for computing solar radiation was added to the repo. This is faster than pysolar and also more accurate in that it produces values closer to ERA5, which is what the models were trained on.

The solar radiation feature is computed automatically by extract_input_target_times (see Colab notebook) as long as it's missing from the examples. If it's present it won't be overridden.