diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4e65bffd..d5126455 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,10 +5,18 @@ Changelog for cfgrib 0.9.9.0 (unreleased) -------------------- +- Depend on the ECMWF `eccodes python package `_ to access + the low level ecCodes C-library, dropping all other GRIB decoding options. + See: `#95 `_, + `#14 `_. + `#204 `_, + `#147 `_ and + `#141 `_. - Many performance improvements during the generation of the index and during data access. - See: `#142 `_. + See: `#142 `_ and + `#197 `_. - ``filter_by_keys`` now can select on all keys known to *ecCodes* without the need to - add non default ones to ``read_keys`` explicitely. + add non default ones to ``read_keys`` explicitly. See: `#187 `_. - Fixed issue where could not load a GRIB message that has only one grid point. See: `#199 `_. diff --git a/README.rst b/README.rst index 48699761..6ad8bb36 100644 --- a/README.rst +++ b/README.rst @@ -11,29 +11,30 @@ The high level API is designed to support a GRIB engine for `xarray `_ and `h5netcdf `_. Low level access and decoding is performed via the -`ECMWF ecCodes library `_. +`ECMWF ecCodes library `_ and +the `eccodes python package `_. Features with development status **Beta**: - enables the ``engine='cfgrib'`` option to read GRIB files with *xarray*, - reads most GRIB 1 and 2 files including heterogeneous ones with ``cfgrib.open_datasets``, -- supports all modern versions of Python 3.9, 3.8, 3.7, 3.6 and PyPy3, +- supports all modern versions of Python 3.9, 3.8, 3.7 and PyPy3, - the 0.9.6.x series with support for Python 2 will stay active and receive critical bugfixes, -- works on *Linux*, *MacOS* and *Windows*, the *ecCodes* C-library is the only binary dependency, +- works wherever *eccodes-python* does: *Linux*, *MacOS* and *Windows* - conda-forge package on all supported platforms, - reads the data lazily and efficiently in terms of both memory usage and disk access, -- allows larger-than-memory and distributed processing via *dask*, +- allows larger-than-memory and distributed processing via *xarray* and *dask*, - supports translating coordinates to different data models and naming conventions, - supports writing the index of a GRIB file to disk, to save a full-file scan on open. Work in progress: -- **Alpha** install a ``cfgrib`` utility that can convert a GRIB file ``to_netcdf`` +- **Beta** install a ``cfgrib`` utility that can convert a GRIB file ``to_netcdf`` with a optional conversion to a specific coordinates data model, see `#40 `_. -- **Alpha** support writing carefully-crafted ``xarray.Dataset``'s to a GRIB1 or GRIB2 file, - see the *Advanced write usage* section below and - `#18 `_. +- **Alpha/Broken** support writing carefully-crafted ``xarray.Dataset``'s to a GRIB1 or GRIB2 file, + see the *Advanced write usage* section below, `#18 `_ + and `#156 `_. Limitations: @@ -58,14 +59,14 @@ Python package from *PyPI* with:: Binary dependencies ------------------- -The Python module depends on the `eccodes python package `_ +*cfgrib* depends on the `eccodes python package `_ to access the ECMWF *ecCodes* binary library, when not using *conda* please follow the *System dependencies* section there. You may run a simple selfcheck command to ensure that your system is set up correctly:: $ python -m cfgrib selfcheck - Found: ecCodes v2.19.0. + Found: ecCodes v2.20.0. Your system is ready. @@ -82,9 +83,9 @@ Read-only *xarray* GRIB engine ------------------------------ Most of *cfgrib* users want to open a GRIB file as a ``xarray.Dataset`` and -need to have *xarray>=0.12.0* installed:: +need to have *xarray* installed:: - $ pip install xarray>=0.12.0 + $ pip install xarray In a Python interpreter try: @@ -827,7 +828,7 @@ See also the list of `contributors None + import xarray as xr + + import cf2cdm + + # NOTE: noop if no input argument + if len(inpaths) == 0: + return + + if len(inpaths) == 1: + # avoid to depend on dask when passing only one file + ds = xr.open_dataset(inpaths[0], engine=engine) # type: ignore + else: + ds = xr.open_mfdataset(inpaths, engine=engine, combine="by_coords") # type: ignore + + if cdm: + coord_model = getattr(cf2cdm, cdm) + ds = cf2cdm.translate_coords(ds, coord_model=coord_model) + + if variable: + ds_or_da = ds[variable] + else: + ds_or_da = ds + + print(ds_or_da) + + if __name__ == "__main__": # pragma: no cover cfgrib_cli() diff --git a/cfgrib/cfmessage.py b/cfgrib/cfmessage.py index 71d7d403..6e6763d6 100644 --- a/cfgrib/cfmessage.py +++ b/cfgrib/cfmessage.py @@ -1,5 +1,5 @@ # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cfgrib/dataset.py b/cfgrib/dataset.py index c408f75a..4cbf930b 100644 --- a/cfgrib/dataset.py +++ b/cfgrib/dataset.py @@ -1,5 +1,5 @@ # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cfgrib/eccodes.h b/cfgrib/eccodes.h deleted file mode 100644 index 2efd86ea..00000000 --- a/cfgrib/eccodes.h +++ /dev/null @@ -1,375 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -/*! \file eccodes.h - \brief The ecCodes C header file - - This is the only file that must be included to use the ecCodes library - from C. -*/ - -/*! Codes handle, structure giving access to parsed values by keys - \ingroup codes_handle - \struct codes_handle -*/ -typedef struct grib_handle codes_handle; - -/*! Codes context, structure containing the memory methods, the parsers and the formats. - \ingroup codes_context - \struct codes_context -*/ -typedef struct grib_context codes_context; - -/*! Codes keys iterator. Iterator over keys. - \ingroup keys_iterator - \struct codes_keys_iterator -*/ -typedef struct grib_keys_iterator codes_keys_iterator; - -/** -* Create a handle from a file resource. -* The file is read until a message is found. The message is then copied. -* Remember always to delete the handle when it is not needed anymore to avoid -* memory leaks. -* -* @param c : the context from which the handle will be created (NULL for default context) -* @param f : the file resource -* @param product : the kind of product e.g. PRODUCT_GRIB, PRODUCT_BUFR -* @param error : error code set if the returned handle is NULL and the end of file is not reached -* @return the new handle, NULL if the resource is invalid or a problem is encountered -*/ -codes_handle* codes_handle_new_from_file(codes_context* c, FILE* f, ProductKind product, int* error); - -/** -* Write a coded message to a file. -* -* @param h : codes_handle to be written -* @param file : name of the output file -* @param mode : mode -* @return 0 if OK, integer value on error -*/ -int codes_write_message(const codes_handle* h, const char* file, const char* mode); - -/** - * Create a handle from a GRIB message contained in the samples directory. - * The message is copied at the creation of the handle - * - * @param c : the context from which the handle will be created (NULL for default context) - * @param sample_name : the name of the sample file (without the .tmpl extension) - * @return the new handle, NULL if the resource is invalid or a problem is encountered - */ -codes_handle* codes_grib_handle_new_from_samples(codes_context* c, const char* sample_name); - -/** - * Create a handle from a BUFR message contained in a samples directory. - * The message is copied at the creation of the handle - * - * @param c : the context from which the handle will be created (NULL for default context) - * @param sample_name : the name of the sample file (without the .tmpl extension) - * @return the new handle, NULL if the resource is invalid or a problem is encountered - */ -codes_handle* codes_bufr_handle_new_from_samples(codes_context* c, const char* sample_name); - - -/** -* Clone an existing handle using the context of the original handle, -* The message is copied and reparsed -* -* @param h : The handle to be cloned -* @return the new handle, NULL if the message is invalid or a problem is encountered -*/ -codes_handle* codes_handle_clone(const codes_handle* h); - -/** -* Frees a handle, also frees the message if it is not a user message -* @see codes_handle_new_from_message -* @param h : The handle to be deleted -* @return 0 if OK, integer value on error -*/ -int codes_handle_delete(codes_handle* h); - -/*! \defgroup handling_coded_messages Handling coded messages */ -/*! @{ */ -/** -* getting the message attached to a handle -* -* @param h : the handle to which the buffer should be gathered -* @param message : the pointer to be set to the handle's data -* @param message_length : On exit, the message size in number of bytes -* @return 0 if OK, integer value on error -*/ -int codes_get_message(const codes_handle* h, const void** message, size_t* message_length); - -/** -* Get latitude/longitude and data values. -* The Latitudes, longitudes and values arrays must be properly allocated by the caller. -* Their required dimension can be obtained by getting the value of the integer key "numberOfPoints". -* -* @param h : handle from which geography and data values are taken -* @param lats : returned array of latitudes -* @param lons : returned array of longitudes -* @param values : returned array of data values -* @return 0 if OK, integer value on error -*/ -int codes_grib_get_data(const codes_handle* h, double* lats, double* lons, double* values); - -/** -* Get the number of coded value from a key, if several keys of the same name are present, the total sum is returned -* -* @param h : the handle to get the offset from -* @param key : the key to be searched -* @param size : the address of a size_t where the size will be set -* @return 0 if OK, integer value on error -*/ -int codes_get_size(const codes_handle* h, const char* key, size_t* size); - -/** -* Get the length of the string representation of the key, if several keys of the same name are present, the maximum length is returned -* -* @param h : the handle to get the offset from -* @param key : the key to be searched -* @param length : the address of a size_t where the length will be set -* @return 0 if OK, integer value on error -*/ -int codes_get_length(const codes_handle* h, const char* key, size_t* length); - -/** -* Get a long value from a key, if several keys of the same name are present, the last one is returned -* @see codes_set_long -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param value : the address of a long where the data will be retrieved -* @return 0 if OK, integer value on error -*/ -int codes_get_long(const codes_handle* h, const char* key, long* value); - -/** -* Get a double value from a key, if several keys of the same name are present, the last one is returned -* @see codes_set_double -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param value : the address of a double where the data will be retrieved -* @return 0 if OK, integer value on error -*/ -int codes_get_double(const codes_handle* h, const char* key, double* value); - -/** -* Get a string value from a key, if several keys of the same name are present, the last one is returned -* @see codes_set_string -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param mesg : the address of a string where the data will be retrieved -* @param length : the address of a size_t that contains allocated length of the string on input, and that contains the actual length of the string on output -* @return 0 if OK, integer value on error -*/ -int codes_get_string(const codes_handle* h, const char* key, char* mesg, size_t* length); - -/** -* Get string array values from a key. If several keys of the same name are present, the last one is returned -* @see codes_set_string_array -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param vals : the address of a string array where the data will be retrieved -* @param length : the address of a size_t that contains allocated length of the array on input, and that contains the actual length of the array on output -* @return 0 if OK, integer value on error -*/ -int codes_get_string_array(const codes_handle* h, const char* key, char** vals, size_t* length); - -/** -* Get raw bytes values from a key. If several keys of the same name are present, the last one is returned -* @see codes_set_bytes -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param bytes : the address of a byte array where the data will be retrieved -* @param length : the address of a size_t that contains allocated length of the byte array on input, and that contains the actual length of the byte array on output -* @return 0 if OK, integer value on error -*/ -int codes_get_bytes(const codes_handle* h, const char* key, unsigned char* bytes, size_t* length); - -/** -* Get double array values from a key. If several keys of the same name are present, the last one is returned -* @see codes_set_double_array -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param vals : the address of a double array where the data will be retrieved -* @param length : the address of a size_t that contains allocated length of the double array on input, and that contains the actual length of the double array on output -* @return 0 if OK, integer value on error -*/ -int codes_get_double_array(const codes_handle* h, const char* key, double* vals, size_t* length); - -/** -* Get long array values from a key. If several keys of the same name are present, the last one is returned -* @see codes_set_long_array -* -* @param h : the handle to get the data from -* @param key : the key to be searched -* @param vals : the address of a long array where the data will be retrieved -* @param length : the address of a size_t that contains allocated length of the long array on input, and that contains the actual length of the long array on output -* @return 0 if OK, integer value on error -*/ -int codes_get_long_array(const codes_handle* h, const char* key, long* vals, size_t* length); - -/** -* Set a long value from a key. If several keys of the same name are present, the last one is set -* @see codes_get_long -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param val : a long where the data will be read -* @return 0 if OK, integer value on error -*/ -int codes_set_long(codes_handle* h, const char* key, long val); - -/** -* Set a double value from a key. If several keys of the same name are present, the last one is set -* @see codes_get_double -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param val : a double where the data will be read -* @return 0 if OK, integer value on error -*/ -int codes_set_double(codes_handle* h, const char* key, double val); - -/** -* Set a string value from a key. If several keys of the same name are present, the last one is set -* @see codes_get_string -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param mesg : the address of a string where the data will be read -* @param length : the address of a size_t that contains the length of the string on input, and that contains the actual packed length of the string on output -* @return 0 if OK, integer value on error -*/ -int codes_set_string(codes_handle* h, const char* key, const char* mesg, size_t* length); - -/** -* Set a bytes array from a key. If several keys of the same name are present, the last one is set -* @see codes_get_bytes -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param bytes : the address of a byte array where the data will be read -* @param length : the address of a size_t that contains the length of the byte array on input, and that contains the actual packed length of the byte array on output -* @return 0 if OK, integer value on error -*/ -int codes_set_bytes(codes_handle* h, const char* key, const unsigned char* bytes, size_t* length); - -/** -* Set a double array from a key. If several keys of the same name are present, the last one is set -* @see codes_get_double_array -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param vals : the address of a double array where the data will be read -* @param length : a size_t that contains the length of the byte array on input -* @return 0 if OK, integer value on error -*/ -int codes_set_double_array(codes_handle* h, const char* key, const double* vals, size_t length); - -/** -* Set a long array from a key. If several keys of the same name are present, the last one is set -* @see codes_get_long_array -* -* @param h : the handle to set the data to -* @param key : the key to be searched -* @param vals : the address of a long array where the data will be read -* @param length : a size_t that contains the length of the long array on input -* @return 0 if OK, integer value on error -*/ -int codes_set_long_array(codes_handle* h, const char* key, const long* vals, size_t length); - -/** -* Get the static default context -* -* @return the default context, NULL it the context is not available -*/ -codes_context* codes_context_get_default(void); - -/** -* Frees the cached definition files of the context -* -* @param c : the context to be deleted -*/ -void codes_context_delete(codes_context* c); - -/** -* Turn on support for multiple fields in single GRIB messages -* -* @param c : the context to be modified -*/ -void codes_grib_multi_support_on(codes_context* c); - -/** -* Turn off support for multiple fields in single GRIB messages -* -* @param c : the context to be modified -*/ -void codes_grib_multi_support_off(codes_context* c); - -/** -* Reset file handle in multiple GRIB field support mode -* -* @param c : the context to be modified -* @param f : the file pointer -*/ -void codes_grib_multi_support_reset_file(codes_context* c, FILE* f); - -char* codes_samples_path(const codes_context* c); - -/** -* Get the API version -* -* @return API version -*/ -long codes_get_api_version(void); - -/*! \defgroup keys_iterator Iterating on keys names -The keys iterator is designed to get the key names defined in a message. -Key names on which the iteration is carried out can be filtered through their -attributes or by the namespace they belong to. -*/ -/*! @{ */ -/*! Create a new iterator from a valid and initialised handle. -* @param h : the handle whose keys you want to iterate -* @param filter_flags : flags to filter out some of the keys through their attributes -* @param name_space : if not null the iteration is carried out only on -* keys belonging to the namespace passed. (NULL for all the keys) -* @return keys iterator ready to iterate through keys according to filter_flags -* and namespace -*/ -codes_keys_iterator* codes_keys_iterator_new(codes_handle* h, unsigned long filter_flags, const char* name_space); - -/*! Step to the next item from the keys iterator. -* @param kiter : valid codes_keys_iterator -* @return 1 if next iterator exists, 0 if no more elements to iterate on -*/ -int codes_keys_iterator_next(codes_keys_iterator* kiter); - - -/*! get the key name from the keys iterator -* @param kiter : valid codes_keys_iterator -* @return key name -*/ -const char* codes_keys_iterator_get_name(const codes_keys_iterator* kiter); - -/*! Delete the keys iterator. -* @param kiter : valid codes_keys_iterator -* @return 0 if OK, integer value on error -*/ -int codes_keys_iterator_delete(codes_keys_iterator* kiter); -int codes_get_native_type(const codes_handle* h, const char* name, int* type); - diff --git a/cfgrib/grib_api.h b/cfgrib/grib_api.h deleted file mode 100644 index 39fa57ce..00000000 --- a/cfgrib/grib_api.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2005-2018 ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -/*! \file grib_api.h - \brief grib_api C header file - -*/ - -typedef enum ProductKind {PRODUCT_ANY, PRODUCT_GRIB, PRODUCT_BUFR, PRODUCT_METAR, PRODUCT_GTS, PRODUCT_TAF} ProductKind; - -/* Types */ -/* undefined */ -#define GRIB_TYPE_UNDEFINED 0 -/* long integer */ -#define GRIB_TYPE_LONG 1 -/* double */ -#define GRIB_TYPE_DOUBLE 2 -/* char* */ -#define GRIB_TYPE_STRING 3 -/* bytes */ -#define GRIB_TYPE_BYTES 4 -/* section */ -#define GRIB_TYPE_SECTION 5 -/* label */ -#define GRIB_TYPE_LABEL 6 -/* missing */ -#define GRIB_TYPE_MISSING 7 - -/*! Grib handle, structure giving access to parsed message values by keys - \ingroup grib_handle -*/ -typedef struct grib_handle grib_handle; - -/*! Grib context, structure containing the memory methods, the parsers and the formats. - \ingroup grib_context -*/ -typedef struct grib_context grib_context; - -/** -* Convert an error code into a string -* @param code : the error code -* @return the error message -*/ -const char* grib_get_error_message(int code); - -/* The truncation is the Gaussian number (or order) */ -int grib_get_gaussian_latitudes(long truncation,double* latitudes); - -/*! \defgroup errors Error codes -Error codes returned by the grib_api functions. -*/ -/*! @{*/ -/** No error */ -#define GRIB_SUCCESS 0 -/** End of resource reached */ -#define GRIB_END_OF_FILE -1 -/** Internal error */ -#define GRIB_INTERNAL_ERROR -2 -/** Passed buffer is too small */ -#define GRIB_BUFFER_TOO_SMALL -3 -/** Function not yet implemented */ -#define GRIB_NOT_IMPLEMENTED -4 -/** Missing 7777 at end of message */ -#define GRIB_7777_NOT_FOUND -5 -/** Passed array is too small */ -#define GRIB_ARRAY_TOO_SMALL -6 -/** File not found */ -#define GRIB_FILE_NOT_FOUND -7 -/** Code not found in code table */ -#define GRIB_CODE_NOT_FOUND_IN_TABLE -8 -/** Array size mismatch */ -#define GRIB_WRONG_ARRAY_SIZE -9 -/** Key/value not found */ -#define GRIB_NOT_FOUND -10 -/** Input output problem */ -#define GRIB_IO_PROBLEM -11 -/** Message invalid */ -#define GRIB_INVALID_MESSAGE -12 -/** Decoding invalid */ -#define GRIB_DECODING_ERROR -13 -/** Encoding invalid */ -#define GRIB_ENCODING_ERROR -14 -/** Code cannot unpack because of string too small */ -#define GRIB_NO_MORE_IN_SET -15 -/** Problem with calculation of geographic attributes */ -#define GRIB_GEOCALCULUS_PROBLEM -16 -/** Memory allocation error */ -#define GRIB_OUT_OF_MEMORY -17 -/** Value is read only */ -#define GRIB_READ_ONLY -18 -/** Invalid argument */ -#define GRIB_INVALID_ARGUMENT -19 -/** Null handle */ -#define GRIB_NULL_HANDLE -20 -/** Invalid section number */ -#define GRIB_INVALID_SECTION_NUMBER -21 -/** Value cannot be missing */ -#define GRIB_VALUE_CANNOT_BE_MISSING -22 -/** Wrong message length */ -#define GRIB_WRONG_LENGTH -23 -/** Invalid key type */ -#define GRIB_INVALID_TYPE -24 -/** Unable to set step */ -#define GRIB_WRONG_STEP -25 -/** Wrong units for step (step must be integer) */ -#define GRIB_WRONG_STEP_UNIT -26 -/** Invalid file id */ -#define GRIB_INVALID_FILE -27 -/** Invalid grib id */ -#define GRIB_INVALID_GRIB -28 -/** Invalid index id */ -#define GRIB_INVALID_INDEX -29 -/** Invalid iterator id */ -#define GRIB_INVALID_ITERATOR -30 -/** Invalid keys iterator id */ -#define GRIB_INVALID_KEYS_ITERATOR -31 -/** Invalid nearest id */ -#define GRIB_INVALID_NEAREST -32 -/** Invalid order by */ -#define GRIB_INVALID_ORDERBY -33 -/** Missing a key from the fieldset */ -#define GRIB_MISSING_KEY -34 -/** The point is out of the grid area */ -#define GRIB_OUT_OF_AREA -35 -/** Concept no match */ -#define GRIB_CONCEPT_NO_MATCH -36 -/** Hash array no match */ -#define GRIB_HASH_ARRAY_NO_MATCH -37 -/** Definitions files not found */ -#define GRIB_NO_DEFINITIONS -38 -/** Wrong type while packing */ -#define GRIB_WRONG_TYPE -39 -/** End of resource */ -#define GRIB_END -40 -/** Unable to code a field without values */ -#define GRIB_NO_VALUES -41 -/** Grid description is wrong or inconsistent */ -#define GRIB_WRONG_GRID -42 -/** End of index reached */ -#define GRIB_END_OF_INDEX -43 -/** Null index */ -#define GRIB_NULL_INDEX -44 -/** End of resource reached when reading message */ -#define GRIB_PREMATURE_END_OF_FILE -45 -/** An internal array is too small */ -#define GRIB_INTERNAL_ARRAY_TOO_SMALL -46 -/** Message is too large for the current architecture */ -#define GRIB_MESSAGE_TOO_LARGE -47 -/** Constant field */ -#define GRIB_CONSTANT_FIELD -48 -/** Switch unable to find a matching case */ -#define GRIB_SWITCH_NO_MATCH -49 -/** Underflow */ -#define GRIB_UNDERFLOW -50 -/** Message malformed */ -#define GRIB_MESSAGE_MALFORMED -51 -/** Index is corrupted */ -#define GRIB_CORRUPTED_INDEX -52 -/** Invalid number of bits per value */ -#define GRIB_INVALID_BPV -53 -/** Edition of two messages is different */ -#define GRIB_DIFFERENT_EDITION -54 -/** Value is different */ -#define GRIB_VALUE_DIFFERENT -55 -/** Invalid key value */ -#define GRIB_INVALID_KEY_VALUE -56 -/** String is smaller than requested */ -#define GRIB_STRING_TOO_SMALL -57 -/** Wrong type conversion */ -#define GRIB_WRONG_CONVERSION -58 -/** Missing BUFR table entry for descriptor */ -#define GRIB_MISSING_BUFR_ENTRY -59 -/** Null pointer */ -#define GRIB_NULL_POINTER -60 -/** Attribute is already present, cannot add */ -#define GRIB_ATTRIBUTE_CLASH -61 -/** Too many attributes. Increase MAX_ACCESSOR_ATTRIBUTES */ -#define GRIB_TOO_MANY_ATTRIBUTES -62 -/** Attribute not found. */ -#define GRIB_ATTRIBUTE_NOT_FOUND -63 -/** Edition not supported. */ -#define GRIB_UNSUPPORTED_EDITION -64 -/** Value out of coding range */ -#define GRIB_OUT_OF_RANGE -65 -/** Size of bitmap is incorrect */ -#define GRIB_WRONG_BITMAP_SIZE -66 -/*! @}*/ diff --git a/cfgrib/messages.py b/cfgrib/messages.py index 6321d4c0..302c6060 100644 --- a/cfgrib/messages.py +++ b/cfgrib/messages.py @@ -1,5 +1,5 @@ # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cfgrib/xarray_store.py b/cfgrib/xarray_store.py index a1ed7b8a..12059547 100644 --- a/cfgrib/xarray_store.py +++ b/cfgrib/xarray_store.py @@ -1,5 +1,5 @@ # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cfgrib/xarray_to_grib.py b/cfgrib/xarray_to_grib.py index ab234fa0..363afea8 100644 --- a/cfgrib/xarray_to_grib.py +++ b/cfgrib/xarray_to_grib.py @@ -1,5 +1,5 @@ # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/docs/conf.py b/docs/conf.py index 1954070d..b9405aec 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,7 +33,7 @@ # General information about the project. project = u"cfgrib" -copyright = u"2017-2020, European Centre for Medium-Range Weather Forecasts (ECMWF)." +copyright = u"2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF)." # The version info for the project you're documenting, acts as replacement # for |version| and |release|, also used in various other places throughout diff --git a/setup.py b/setup.py index f8e11cad..9a315a57 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017-2020 European Centre for Medium-Range Weather Forecasts (ECMWF). +# Copyright 2017-2021 European Centre for Medium-Range Weather Forecasts (ECMWF). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/test_20_main_to_netcdf.py b/tests/test_20_main_commands.py similarity index 63% rename from tests/test_20_main_to_netcdf.py rename to tests/test_20_main_commands.py index e4a90e39..5fc9da6e 100644 --- a/tests/test_20_main_to_netcdf.py +++ b/tests/test_20_main_commands.py @@ -30,3 +30,22 @@ def test_cfgrib_cli_to_netcdf(tmpdir): assert res.exit_code == 0 assert res.output == "" + + +def test_cfgrib_cli_dump(): + runner = click.testing.CliRunner() + + res = runner.invoke(__main__.cfgrib_cli, ["dump"]) + + assert res.exit_code == 0 + assert res.output == "" + + res = runner.invoke(__main__.cfgrib_cli, ["dump", TEST_DATA]) + + assert res.exit_code == 0 + assert "