While the CDS only has hourly and monthly ERA5/ERA5-Land data, It is possible to use the CDS API to request daily data from the CDS ERA5 daily application:

https://cds.climate.copernicus.eu/cdsapp#!/software/app-c3s-daily-era5-statistics?tab=overview

Please note that to use this method, you need to use the correct syntax.

For valid keywords, see Table 2 of: https://datastore.copernicus-climate.eu/documents/app-c3s-daily-era5-statistics/C3S_Application-Documentation_ERA5-daily-statistics-v2.pdf


This script shows how the daily mean of 2m temperature for all months in 1979 can be retrieved:

Retrieve daily ERA5 data
import cdsapi
import requests

# CDS API script to use CDS service to retrieve daily ERA5* variables and iterate over 
# all months in the specified years.

# Requires:
# 1) the CDS API to be installed and working on your system
# 2) You have agreed to the ERA5 Licence (via the CDS web page)
# 3) Selection of required variable, daily statistic, etc

# Output:
# 1) separate netCDF file for chosen daily statistic/variable for each month

c = cdsapi.Client(timeout=300)

# Uncomment years as required 

years =  [
            '1979' 
#           ,'1980', '1981',
#            '1982', '1983', '1984',
#            '1985', '1986', '1987',
#            '1988', '1989', '1990',
#            '1991', '1992', '1993',
#            '1994', '1995', '1996',
#            '1997', '1998', '1999',
#            '2000', '2001', '2002',
#            '2003', '2004', '2005',
#            '2006', '2007', '2008',
#            '2009', '2010', '2011',
#            '2012', '2013', '2014',
#            '2015', '2016', '2017',
#            '2018', '2019', '2020',
#            '2021'
] 


# Retrieve all months for a given year.

months = ['01', '02', '03',
            '04', '05', '06',
            '07', '08', '09',
            '10', '11', '12']

# For valid keywords, see Table 2 of:
# https://datastore.copernicus-climate.eu/documents/app-c3s-daily-era5-statistics/C3S_Application-Documentation_ERA5-daily-statistics-v2.pdf

# select your variable; name must be a valid ERA5 CDS API name.
var = "2m_temperature" 

# Select the required statistic, valid names given in link above
stat = "daily_mean"

# Loop over years and months

for yr in years:
    for mn in months:
        result = c.service(
        "tool.toolbox.orchestrator.workflow",
        params={
             "realm": "user-apps",
             "project": "app-c3s-daily-era5-statistics",
             "version": "master",
             "kwargs": {
                 "dataset": "reanalysis-era5-single-levels",
                 "product_type": "reanalysis",
                 "variable": var,
                 "statistic": stat,
                 "year": yr,
                 "month": mn,
                 "time_zone": "UTC+00:0",
                 "frequency": "1-hourly",
#
# Users can change the output grid resolution and selected area 
#
#                "grid": "1.0/1.0",
#                "area":{"lat": [10, 60], "lon": [65, 140]}

                 },
        "workflow_name": "application"
        })
		
# set name of output file for each month (statistic, variable, year, month		

        file_name = "download_" + stat + "_" + var + "_" + yr + "_" + mn + ".nc"
		
        location=result[0]['location']
        res = requests.get(location, stream = True)
        print("Writing data to " + file_name)
        with open(file_name,'wb') as fh:
            for r in res.iter_content(chunk_size = 1024):
                fh.write(r)	
		fh.close()

Hope that helps,

Kevin


44 Comments

  1. Hi Kevin,

    I am trying to retrieve ERA5-Land 2m_temperature daily mean of 1-hourly frequency with grid 0.1/0.1 over area N 50, W -126, S 24, E -66, but I keep getting "Failed (download widget)" from the application and "ValueError: Can't save empty DataArray." when running using the above script (after tweaking parameters). Retrieval works fine when I increase the area to N 90, W -180, S -90, E 180, so I am not sure what exactly is causing the request to fail, but I would like to avoid retrieving data globally if possible. Is there a way to make this work?

    Hope to hear from you,

    Jessica

  2. I have the same problem. 
    It seems the problem is with the size of the grid 0.1x0.1. For size 0.25 x 0.25 it works fine.


  3. Hi Jessica, Karol

    I think there may be an issue with the Toolbox; I will let you know when it is resolved,

    Thanks,

    Kevin

    1. Hi Kevin


      Any update on this? I am also getting the same error when trying to download at 0.1 deg resolution. It would be great to have the option to download daily data! 


      Thanks!

      Rutger

      1. Hi Rutger,

        The bug has been fixed but the code of the public application still need to be updated.

        In the meanwhile the fixed app is accessible here:  https://cds.climate.copernicus.eu/apps/10207/era5-daily-statistics

        Regards.

        Vivien

  4. Hi Kevin,

    I have a problem when trying to save the file. I usually use r.download('/path/filename.nc'), but now I get this error:

    AttributeError: 'list' object has no attribute 'download'

    If I use instead c.download(r) I get a huge error message. I'd like to download the files in a specific folder, and I didn't understand well how you save them in your code. Is there any way in which I can do that?

    Thanks in advance,

    María Jesús




    1. Hi Maria, 

      Did you find a way to redirect downloads to an specific folder? I am trying to do the same.

      Cheers,

      Carlos. 


  5. Hi Kevin

    Get the same error as described above when trying to download 0.1 x 0.1 deg resolution data.

    Thanks for looking into it. I agree. Having the option to tailor daily statistics from ERA5 will be absolutely great once we get around these issues...

    1. Dear Martin,

      I think the right statistic name is "daily_maximum".

      Regarding the 0.1 x 0.1 deg resolution data it is under investigation.

      Thank you for your patience.

      Vivien

      1. Thanks Vivien. My bad. Obviously haven't read the documentation correctly. Have removed my comment/error message on 'daily_max' from the above. 

  6. Hi Kevin, 

    when using the code above, I always get this error:

    ```

    Traceback (most recent call last):
    File "/usr/local/lib/python3.6/dist-packages/jsonrequest/requests.py", line 71, in jsonrequestcall
    resp = coding.encode(req.callable(*req.args, **req.kwargs), register=encoders, **context)
    File "/usr/local/lib/python3.6/dist-packages/cdsworkflows/submit_workflow.py", line 55, in submit_workflow
    results = workflow_bare_func(**kwargs)
    TypeError: application() missing 1 required positional argument: 'licence'

    ```


    Could you please help with this?

    Many thanks!


    Ting

    1. For those who are experiencing the save issue above, the workaround is actually simple but missed in the code snippet above:

      in the request dict `"kwargs": {...}`, just add a keyword pair `"licence":'GPL'`.

      the issue will be gone.

      hope this helps.

      1. Hi Ting,

        Yes this is a valid work-around, however, it is no longer required as I have made the correction such that the licence field defaults to True for cdsapi users.

        FYI, the purpose of the new key word argument was to ensure that non-registered CDS users are required to agree to the Copernicus licence when using the gui version of the application.

        Thanks,

        Eddy

  7. Hi Kevin, 

    When running the above python code my task is stuck in a Queued status for around two hours or so before being processed. The actual "In Progress" time is only a few mintues. This still occures when this is the only task being processed. 

    When running the task throught the online app the task goes imediatly to "In Progress" and finishes reletivly quickly.

    Just wanted to check and ask why this happend.


    I also wasnted to ask is there is any parrelel processing occuring if multiple tasks are sent in at the same time. 


    Thanks for your help,

    -Thomas Ott

    1. Hi Thomas,

      Internally, the CDS manages the request load from the web interface, the CDS API and the Toolbox, as there are a limited number of processing slots available. The CDS is also undergoing constant evolution and system sessions to implement the changes can affect processing times.

      You can see the CDS status via the 'live' page: 

      https://cds.climate.copernicus.eu/live/

      and you can see the number of simultaneous requests a user can submit at:

      https://cds.climate.copernicus.eu/live/limits

      Hope that helps,

      Kevin

  8. Hi Kevin,

    Thanks for this, it will be great to have access to daily data.

    I tried using your original script and it worked well to retrieve data globally at a 1 x 1 resolution. However, once I specify a different grid resolution (0.25 x 0.25) and particular sets of lat/long (as suggested in your script) I get different types of errors.

    I also tried using the "License: GPL" fix suggested above by Ting Su but that does not seem to help.  

    The queue times are quite long so it is difficult to try different script variations.

    Any feedback will be much appreciated. 

    Regards,

    Carlos. 

    1. Hi Carlos,

      There were some CDS system session over the past week which affected performance and may have been the cause of the errors you saw/long queue times. 

      Is it working ok for you now?

      Thanks,

      Kevin

      1. Hi Kevin, 

        Thank you for your reply. I am afraid I am experiencing the same issues in terms of the queue (at least yesterday and today). As such, I am not sure if the script is working properly. The queue is taking too long!

        Any feedback will be much appreciated, 

        Cheers,

        Carlos. 

  9. Thanks for providing the script for daily statistics, that's indeed really helpful!

    I just tested the script above and it works like a charm. However, I noticed a reduction in download speed when changing the resolution. This is in particular strange since I want to download "low" resolution data (1.0 x 1.0 degree) compared to the default (0.25 x 0.25 degree). While the latter downloads about 1 month / min, I didn't obtain a single month after 10 min for the "low" resolution data.

    Is this normal behavior?

  10. hi Niclas,

    I suspect this is mainly due to the data being re-interpolated; CDS ERA5 atmospheric data are stored on a 0.25 degree grid, so even though you request them at a lower resolution, the data have to be re-interpolated to the 1.0 degree grid, while the 0.25 degree data are delivered 'direct' from the CDS data store,

    Thanks,

    Kevin

  11. I have a problem with getting the reanalysis mean daily Surface solar radiation downwards, 1 hourly, 0.25/0.25. For January 2021 I get a variable called rsds in w m-2, whilst for the rest of the year I get a variable called rsds_accumulated and in j m-2. from February 2021 the variable is "integral_wrt_time_of_surface_downwelling_shortwave_flux_in_air" which is the sum of the values over a day. Why does the January data differ? I checked other years with the same problem.

    Any feedback would be appreciated.

    Thank you,

    Cristian

    1. Hi Cristian Gudasz ,

      Apologies for this, we recently changed how accumulated variables were handled in the toolbox and applications. Previously they were converted to rate values (rsds), however this proved problematic as the conversions were not consistent accross datasets and resulted in data differering to what was documented on the catalogue entry page. We have removed all the conversions such that now you get the data as it is described on the catalogue entry, which in this case is the accumulated radiation (rsds_accumulated) during the model timestep.

      The problem you experienced here was that you were receiving an old, cached, result from before we made this change for the January request. I have removed this result (and others like it) from our cache such that when you submit the request again you will get the accumulated data. Note that they are equivalent, just different ways of representing the same quantity, and I apologise again for any inconvenience/confusion caused.

      Also, if you want to continue using the rate type data (which I personally prefer), you should request the variable:

      'Mean surface downward short-wave radiation flux'

      All the variable descriptions can be found here, and the daily stats app now serves the data as described in this table:

      https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-single-levels?tab=overview

      Thanks,

      Eddy

      1. Hi Eddy,

        Thank you for the clarification! That really helps but downloading the January file, the problem is still there.

        In the daily widget you can chose chose to download the mean of 1 hourly daily mean of the Mean surface downward short-wave radiation flux as well as the 1 hourly daily mean of the surface downward short-wave radiation flux. Since a mean here signifies in this case an accumulated quantity over a period, (in this case a day) both are producing the same results. Did I get that right?

        Looking at the same year and month in the Land dataset with 0.1/0.1 grid and download the daily mean for the same rsds parameter the value is rsds_accumulated in J m-2. This would be the sum over the whole day. Dividing to 86400 to get w m-2 should be about the same values as in the example above, but they are not. They are about 50% lower. Any thoughts why this is?

        Thank you again!
        Cristian

        1. For the first question regarding the ERA5-single-levels data:

          The "Mean surface downward short-wave radiation flux" is in units of W m-2 (= J s-1 m-2) therefore this is a rate variable, so the daily mean of this will be the mean rate for the day.

          The "Surface solar radiation downwards" is in units of J m-2 therefore this is an accumulated variable. It is the accumulation during the model time-step, therefore the daily mean will be the mean hourly accumulation of radiation... which could also be considered a rate variable with units J hour-1 m-2. This potential for confusion is why I prefer the mean rate variables, these accumulated variables are very useful in some instances (e.g. estimating energy transfer), but for a general understanding of the state of the climate they are a bit confusing.

          For the second question regarding the ERA5 land data, this is a bug in the application, it does not correctly handle the daily accumulated variables which ERA5 land produces. As a temporary solution I have disabled the variables which are not being handled correctly. I have informed the application developers of this and a correct handling of the accumulted vairables will be made available soon. Note this only effects the ERA5 land data, for the other ERA5 single levels and ERA5 pressure levels only accumulate for the model time step, therefore the daily aggregation is correct.

          Thanks,

          Eddy

  12. I'm having trouble trying to get Daily Maximum 2m temperature data for February 1958, with both ERA5/ERA5-Land at any geographical coordinates (using the daily application). It won´t download, it remains queued permanently. I didn´t have this problem getting Daily Minimum data for February 1958, or any variable for any other time period.

    So I tried getting Daily Mean 2m temperature data from the 'ERA5-Land hourly data from 1950 to present' dataset, and while it did download, data for February 27th, 1958 is missing, shown as 'NaN'

    Is it an error that Daily Maximum/Mean temperature data from this particular day is missing on both the application and the dataset?


    Thanks



    1. Hi Fred,

      I can see data for 27th February 1958 everywhere except the sea as expected in ERA5-Land.

      Thanks

      Michela

  13. Hi all,

    I am trying to download ERA5-Land data (mean, max, min daily t2m) using the code above.
    I get an error when I change the time_zone parameter to UTC+01:00 instead of UTC+00:00 as default.

    I started to download data from January 2001 onward, and when my script reaches October 2002 I get the following error:


    2022-03-17 09:33:10,559 INFO Sending request to https://cds.climate.copernicus.eu/api/v2/tasks/services/tool/toolbox/orchestrator/workflow/clientid-1cc7f1fe6b8e46bc8d663ba4f83ac462
    2022-03-17 09:33:11,243 INFO Request is queued
    2022-03-17 09:33:12,432 INFO Request is running
    2022-03-17 09:33:14,126 INFO Request is failed
    2022-03-17 09:33:14,128 ERROR Message: 
    2022-03-17 09:33:14,130 ERROR Reason:  Traceback (most recent call last):
      File "/opt/cdstoolbox/cdscompute/cdscompute/cdshandlers/services/handler.py", line 59, in handle_request
        result = cached(context.method, proc, context, context.args, context.kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/caching.py", line 108, in cached
        result = proc(context, *context.args, **context.kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 124, in __call__
        return p(*args, **kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 60, in __call__
        return self.proc(context, *args, **kwargs)
      File "/home/cds/cdsservices/services/python_service.py", line 38, in execute
        raise exceptions.InternalError(logging + traceback, '')
    cdsclient.exceptions.InternalError: Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in _dataset_concat
        vars = ensure_common_dims([ds.variables[k] for ds in datasets])
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in <listcomp>
        vars = ensure_common_dims([ds.variables[k] for ds in datasets])
      File "/usr/local/lib/python3.6/site-packages/xarray/core/utils.py", line 426, in __getitem__
        return self.mapping[key]
    KeyError: 'experimentVersionNumber'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/opt/cdstoolbox/jsonrequest/jsonrequest/requests.py", line 71, in jsonrequestcall
        resp = coding.encode(req.callable(*req.args, **req.kwargs), register=encoders, **context)
      File "/opt/cdstoolbox/cdstools/cdstools/util.py", line 854, in concat
        return xr.concat(data, dim, **kwargs)
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 192, in concat
        objs, dim, data_vars, coords, compat, positions, fill_value, join, combine_attrs
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 527, in _dataarray_concat
        combine_attrs="drop",
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 462, in _dataset_concat
        raise ValueError("%r is not present in all datasets." % k)
    ValueError: 'experimentVersionNumber' is not present in all datasets.
    2022-03-17 09:33:14,132 ERROR   Traceback (most recent call last):
    2022-03-17 09:33:14,134 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/cdshandlers/services/handler.py", line 59, in handle_request
    2022-03-17 09:33:14,136 ERROR       result = cached(context.method, proc, context, context.args, context.kwargs)
    2022-03-17 09:33:14,137 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/caching.py", line 108, in cached
    2022-03-17 09:33:14,138 ERROR       result = proc(context, *context.args, **context.kwargs)
    2022-03-17 09:33:14,139 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 124, in __call__
    2022-03-17 09:33:14,140 ERROR       return p(*args, **kwargs)
    2022-03-17 09:33:14,140 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 60, in __call__
    2022-03-17 09:33:14,141 ERROR       return self.proc(context, *args, **kwargs)
    2022-03-17 09:33:14,142 ERROR     File "/home/cds/cdsservices/services/workflow.py", line 35, in execute
    2022-03-17 09:33:14,143 ERROR       raise exceptions.CDSException(True, True, logging + traceback, '', uri)
    2022-03-17 09:33:14,143 ERROR   cdsclient.exceptions.CDSException: Traceback (most recent call last):
    2022-03-17 09:33:14,144 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/cdshandlers/services/handler.py", line 59, in handle_request
    2022-03-17 09:33:14,145 ERROR       result = cached(context.method, proc, context, context.args, context.kwargs)
    2022-03-17 09:33:14,145 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/caching.py", line 108, in cached
    2022-03-17 09:33:14,146 ERROR       result = proc(context, *context.args, **context.kwargs)
    2022-03-17 09:33:14,147 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 124, in __call__
    2022-03-17 09:33:14,147 ERROR       return p(*args, **kwargs)
    2022-03-17 09:33:14,148 ERROR     File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 60, in __call__
    2022-03-17 09:33:14,149 ERROR       return self.proc(context, *args, **kwargs)
    2022-03-17 09:33:14,150 ERROR     File "/home/cds/cdsservices/services/python_service.py", line 38, in execute
    2022-03-17 09:33:14,150 ERROR       raise exceptions.InternalError(logging + traceback, '')
    2022-03-17 09:33:14,151 ERROR   cdsclient.exceptions.InternalError: Traceback (most recent call last):
    2022-03-17 09:33:14,152 ERROR     File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in _dataset_concat
    2022-03-17 09:33:14,152 ERROR       vars = ensure_common_dims([ds.variables[k] for ds in datasets])
    2022-03-17 09:33:14,160 ERROR     File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in <listcomp>
    2022-03-17 09:33:14,161 ERROR       vars = ensure_common_dims([ds.variables[k] for ds in datasets])
    2022-03-17 09:33:14,161 ERROR     File "/usr/local/lib/python3.6/site-packages/xarray/core/utils.py", line 426, in __getitem__
    2022-03-17 09:33:14,162 ERROR       return self.mapping[key]
    2022-03-17 09:33:14,163 ERROR   KeyError: 'experimentVersionNumber'

    Traceback (most recent call last):

      File "<ipython-input-5-e88eba735741>", line 1, in <module>
        runfile('/path/to/my/script.py', wdir='/path/to/my/wdir/')

      File "/home/guido/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 827, in runfile
        execfile(filename, namespace)

      File "/home/guido/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 110, in execfile
        exec(compile(f.read(), filename, 'exec'), namespace)

      File "/path/to/my/script.pyF", line 60, in <module>
        "workflow_name": "application"

      File "/home/guido/anaconda3/lib/python3.7/site-packages/cdsapi/api.py", line 319, in service
        result = self._api('%s/tasks/services/%s/clientid-%s' % (self.url, name, uuid.uuid4().hex), request, 'PUT')

      File "/home/guido/anaconda3/lib/python3.7/site-packages/cdsapi/api.py", line 420, in _api
        raise Exception("%s. %s." % (reply['error'].get('message'), reply['error'].get('reason')))

    Exception: . Traceback (most recent call last):
      File "/opt/cdstoolbox/cdscompute/cdscompute/cdshandlers/services/handler.py", line 59, in handle_request
        result = cached(context.method, proc, context, context.args, context.kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/caching.py", line 108, in cached
        result = proc(context, *context.args, **context.kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 124, in __call__
        return p(*args, **kwargs)
      File "/opt/cdstoolbox/cdscompute/cdscompute/services.py", line 60, in __call__
        return self.proc(context, *args, **kwargs)
      File "/home/cds/cdsservices/services/python_service.py", line 38, in execute
        raise exceptions.InternalError(logging + traceback, '')
    cdsclient.exceptions.InternalError: Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in _dataset_concat
        vars = ensure_common_dims([ds.variables[k] for ds in datasets])
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 460, in <listcomp>
        vars = ensure_common_dims([ds.variables[k] for ds in datasets])
      File "/usr/local/lib/python3.6/site-packages/xarray/core/utils.py", line 426, in __getitem__
        return self.mapping[key]
    KeyError: 'experimentVersionNumber'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/opt/cdstoolbox/jsonrequest/jsonrequest/requests.py", line 71, in jsonrequestcall
        resp = coding.encode(req.callable(*req.args, **req.kwargs), register=encoders, **context)
      File "/opt/cdstoolbox/cdstools/cdstools/util.py", line 854, in concat
        return xr.concat(data, dim, **kwargs)
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 192, in concat
        objs, dim, data_vars, coords, compat, positions, fill_value, join, combine_attrs
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 527, in _dataarray_concat
        combine_attrs="drop",
      File "/usr/local/lib/python3.6/site-packages/xarray/core/concat.py", line 462, in _dataset_concat
        raise ValueError("%r is not present in all datasets." % k)
    ValueError: 'experimentVersionNumber' is not present in all datasets..


    Thank you for your support


  14. Hi Guido,

    looks like this may have been an internal CDS issue related to the internal representation of these data in the CDS, but hopefully that is resolved now. Are you still seeing this error message?

    Kevin

  15. Dear Kevin (or others),

    I have been using this very useful script to retrieve daily ERA5 data at 0.5 degree resolution, but I have a few questions.

    Whatever I fill in for the extent ( either "area": {"lat": [-89.75, 89.75], "lon": [-179.75, 179.75]} or "area": {"lat": [-90, 90], "lon": [-180, 180]}), I only manage to get gridcells with coordinates ending with .0 and 0.5. Is there a way to get the lon and lat coordinates ending at 0.25 and 0.75 (representing their midpoints, and resulting in a grid with exactly 720 lon and 360 lat values)?

    Do I understand correctly that to get daily precipitation values, I need to multiply the final result with 24?

    Does the script include the shift time of -1 hour?

    Thanks! Hester

  16. This script is extremely useful and fills a serious gap in acquiring daily-average ERA5 programmatically! I have one issue though. When I specify an area  that isn't global, the area cropped out is simply replaced with NaNs, which take up a lot of useless memory if you're cropping to a small region.

    I see L712-718 of the app-c3s-daily-era5-statistics  code implements a ct.cube.select  call to crop to the desired region, not sure if that's being called or what's happening: https://cds.climate.copernicus.eu/cdsapp#!/software/app-c3s-daily-era5-statistics?tab=appcode

    I'll implement a manual workaround to crop out the NaNs, but keen to hear if this can be avoided.

    1. Hi Tom,  i tried a request for

      "area": {"lat": [0, 10], "lon": [10, 20]} 

      and it worked as expected - returned files were just for the area selected:

      Can you give an example of a request whihc gives NAN's, please?

      Kevin

      1. Hi Kevin, thank you for your swift response. Given that it worked for you, I decided to test this again this morning. I'm now observing the correct behaviour that you've reported here. I can't think of anything that's changed with my code, so this might just remain a mystery!

        Cheers

        1. Glad it is working for you, Tom!

          Kevin

  17. Hi Kevin, I'm finding that pressure level requests will queue for hours and then fail with the error `cdsworkflows.error.ClientError: None`. I attach an MWE script (requesting daily average geopotential height at 250 hPa) below that should trigger the error. My hypothesis is that the tool will attempt to compute the daily average over all pressure levels before slicing out the pressure level requested, but I'm not sure. Am I missing anything or doing anything wrong?

    import cdsapi
    import requests
    import time
    import numpy as np
    
    def download_era5_daily_avg_month(download_fpath):
        c = cdsapi.Client(timeout=600, retry_max=1000, quiet=False, debug=True)
    
        print(f"\n\n\nDownloading reanalysis data...\n\n")
        tic = time.time()
    
        result = c.service(
            "tool.toolbox.orchestrator.workflow",
            params={
                "realm": "user-apps",
                "project": "app-c3s-daily-era5-statistics",
                "version": "master",
                "kwargs": {
                    "dataset": 'reanalysis-era5-pressure-levels',
                    "product_type": "reanalysis",
                    "variable": "geopotential",
                    "statistic": "daily_mean",
                    "year": 1959,
                    "month": '01',
                    "time_zone": "UTC+00:0",
                    "frequency": "1-hourly",
                    "grid": "0.25/0.25",
                    "pressure_level": "250",
                },
                "workflow_name": "application"
            })
    
        location = result[0]['location']
        res = requests.get(location, stream=True)
        print("Writing data to " + download_fpath)
        with open(download_fpath, 'wb') as fh:
            for r in res.iter_content(chunk_size=1024):
                fh.write(r)
        fh.close()
    
        dur = time.time() - tic
        print(f"\n\nFile downloaded to {download_fpath}\nDone in {np.floor(dur / 60)}m:{dur % 60:.0f}s.\n\n")
    
    download_era5_daily_avg_month('foo.nc')
    1. Hi Tom,

      Sorry for not getting back to you sooner -it looks like there was an issue with the daily app for pre - 1979 ERA5 pressure level data, but this should be fixed now (I did some tests this morning and it worked ok!),

      Thanks,

      Kevin

      1. Seems to be working fine now, thanks very much Kevin et al!

  18. Hi Kevin,

    I am using "area":{"lat": [-90, 90], "lon": [-180, 180] and "grid": "0.25/0.25" as parameter for downloading high cloud cover value. The latitude in the output file ranges from -90 to +90 whereas the longitude ranges from -180 to 179.75 only. 

    What might be the reason why +180 long is not displayed in the data? Am I missing something here? 

    1. hi Rabin, 

      the point at -180 degrees is the same location as +180 degrees, hence only one of these is needed i.e. -180 to +179.75 gives a complete global grid at 0.25 degree resolution,

      Thanks,

      Kevin

  19. Hi, all. I used the scripts (thank to Kevin Marsh ) and only made a modification in

    " ”realm“ :“c3s" " .

    It's ok when I downloaded "2m_temperature".

    But when I downloaded "surface_net_solar_radiation",  the scripts can not go on and the

    error is as below:

    " NameError: name 'reduce' is not defined "

    I only change the name the variable.


    Enviroment : Anaconda 3 + python 3.9.2 


    As a try, I add a line in the scripts "from functools import reduce", But the problem is still there. 


    Similar problem are also reported recent days Re: "NameError: name 'reduce' is not defined" occurred when download ERA5-Land daily statistics


    Does anyone can give some instruction?

    ERA5_daily.py

    Thanks!

  20. Hi Leo,

    I think it was a temporary issue with the daily application on the CDS. The "realm" line should be

    "realm": "user-apps" as in the example above.


    This script works for me:


    % more workflow.py 

    import cdsapi

    import requests

     

    # CDS API script to use CDS service to retrieve daily ERA5* variables and iterate over

    # all months in the specified years.

     

    # Requires:

    # 1) the CDS API to be installed and working on your system

    # 2) You have agreed to the ERA5 Licence (via the CDS web page)

    # 3) Selection of required variable, daily statistic, etc

     

    # Output:

    # 1) separate netCDF file for chosen daily statistic/variable for each month

     

    c = cdsapi.Client(timeout=300)

     

    # Uncomment years as required

     

    years =  [

                '1979'

    #           ,'1980', '1981',

    #            '1982', '1983', '1984',

    #            '1985', '1986', '1987',

    #            '1988', '1989', '1990',

    #            '1991', '1992', '1993',

    #            '1994', '1995', '1996',

    #            '1997', '1998', '1999',

    #            '2000', '2001', '2002',

    #            '2003', '2004', '2005',

    #            '2006', '2007', '2008',

    #            '2009', '2010', '2011',

    #            '2012', '2013', '2014',

    #            '2015', '2016', '2017',

    #            '2018', '2019', '2020',

    #            '2021'

    ]

     

     

    # Retrieve all months for a given year.

     

    months = ['01', '02', '03',

                '04', '05', '06',

                '07', '08', '09',

                '10', '11', '12']

     

    # For valid keywords, see Table 2 of:

    # https://datastore.copernicus-climate.eu/documents/app-c3s-daily-era5-statistics/C3S_Application-Documentation_ERA5-daily-statistics-v2.pdf

     

    # select your variable; name must be a valid ERA5 CDS API name.

    var = "surface_net_solar_radiation"

     

    # Select the required statistic, valid names given in link above

    stat = "daily_mean"

     

    # Loop over years and months

     

    for yr in years:

        for mn in months:

            result = c.service(

            "tool.toolbox.orchestrator.workflow",

            params={

                 "realm": "user-apps",

                 "project": "app-c3s-daily-era5-statistics",

                 "version": "master",

                 "kwargs": {

                     "dataset": "reanalysis-era5-single-levels",

                     "product_type": "reanalysis",

                     "variable": var,

                     "statistic": stat,

                     "year": yr,

                     "month": mn,

                     "time_zone": "UTC+00:0",

                     "frequency": "1-hourly",

    #

    # Users can change the output grid resolution and selected area

    #

    #                "grid": "1.0/1.0",

    #                "area":{"lat": [10, 60], "lon": [65, 140]}

     

                     },

            "workflow_name": "application"

            })

             

    # set name of output file for each month (statistic, variable, year, month     

     

            file_name = "download_" + stat + "_" + var + "_" + yr + "_" + mn + ".nc"

             

            location=result[0]['location']

            res = requests.get(location, stream = True)

            print("Writing data to " + file_name)

            with open(file_name,'wb') as fh:

                for r in res.iter_content(chunk_size = 1024):

                    fh.write(r)

            fh.close()


    which gives:

    % python3 workflow.py

    2023-03-29 14:39:23,123 INFO Welcome to the CDS

    2023-03-29 14:39:23,123 INFO Sending request to https://cds.climate.copernicus.eu/api/v2/tasks/services/tool/toolbox/orchestrator/workflow/clientid-ca92e3febe0b49d18d70984583f3a282

    2023-03-29 14:39:23,194 INFO Request is queued

    2023-03-29 14:53:44,946 INFO Request is running

    2023-03-29 14:55:45,209 INFO Request is completed

    Writing data to download_daily_mean_surface_net_solar_radiation_1979_01.nc

    2023-03-29 14:56:08,137 INFO Welcome to the CDS

    2023-03-29 14:56:08,137 INFO Sending request to https://cds.climate.copernicus.eu/api/v2/tasks/services/tool/toolbox/orchestrator/workflow/clientid-0d0746c3abb8414894ce6abf2d263c53

    2023-03-29 14:56:08,209 INFO Request is queued

    2023-03-29 15:22:29,376 INFO Request is running

    2023-03-29 15:24:29,630 INFO Request is completed

    Writing data to download_daily_mean_surface_net_solar_radiation_1979_02.nc

    ..etc


    (The  ERA5-Land accumulated parameters have been removed from the app as it is fairly straightforward to derive these from the dataset)

    Hope that helps,

    Kevin

  21. Hi Kevin

    I'm curious why I cannot directly download the daily statistics for "total precipitation" in the ERA5-land dataset from the "https://cds.climate.copernicus.eu/apps/user-apps/app-c3s-daily-era5-statistics". Would it be poosible to add this feature in the future? It would greatly benefit users like me who are not proficient in Python.

    Thanks! 

  22. Hi!

    Thanks a lot for sharing the API: it is very helpful for research in different fields.

    In my case, I am trying to retrieve the 'daily_maximum' value for the variable '2m_temperature' from 1950 onwards at 0.1/0.1 grid level. Even though I manage to slowly download the data, I often have the error:[Errno 10054] An existing connection was forcibly closed by the remote host, which obliges to wait 120 second for the next request (the error does not pop up with 0.25/0.25 grid level). I have tried some methods like inserting a sleep timer but it seems to me that in any case the requests are running for a very long time. So my questions are:

    - Is there indeed an issue with the 0.1 grid level?
    - Are the data of the 0.1 grid level resampled from the 0.25 grid or are they source data?

    Thanks!

  23. Hi! I am having trouble running even the example as it is. It finishes downloading the first month but then it fails before going to the 2nd month. This was yesterday. Today can't even download the first month of data.

    These are some of the error messages it threw. Can you help?
    Thanks!

    2023-11-16 18:26:37,983 INFO Request is failed
    2023-11-16 18:26:37,983 ERROR Message: an internal error occurred processing your request
    2023-11-16 18:26:37,984 ERROR Reason:  Cmd('git') failed due to: exit code(128)
      cmdline: git clone git@gitrepo:user-apps/app-c3s-daily-era5-statistics.git /home/cds/compute_workflows/user-apps/app-c3s-daily-era5-statistics/master
      stdout: 'Cloning into '/home/cds/compute_workflows/user-apps/app-c3s-daily-era5-statistics/master'...'
      stderr: 'Warning: Permanently added the RSA host key for IP address '192.168.0.248' to the list of known hosts.
    GitLab: Failed to authorize your Git request: internal API unreachable
    fatal: Could not read from remote repository.

    Please make sure you have the correct access rights
    and the repository exists.'

    1. Hi Michelle,

      are you still having issues when using the daily application?

      Thanks,

      Kevin