From 1d9a4b27a1023fc0637c6cc0b7c4b4f4cb54ecdf Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Tue, 14 Jun 2022 22:11:48 +0100 Subject: [PATCH 1/9] Cleanup --- src/grib_geography.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/grib_geography.c b/src/grib_geography.c index cab00429a..4d76b0b72 100644 --- a/src/grib_geography.c +++ b/src/grib_geography.c @@ -3951,7 +3951,8 @@ static int get_precomputed_latitudes_N640(double* lats) } /* 'trunc' is the Gaussian number (or order) */ -/* i.e. Number of parallels between a pole and the equator */ +/* i.e. Number of parallels between a pole and the equator. */ +/* The provided 'lats' array should have allocated 2*trunc elements */ static int _grib_get_gaussian_latitudes(long trunc, double* lats) { long jlat, iter, legi; @@ -3959,7 +3960,7 @@ static int _grib_get_gaussian_latitudes(long trunc, double* lats) double mem1, mem2, conv; double denom = 0.0; double precision = 1.0E-14; - long nlat = trunc * 2; + const long nlat = trunc * 2; rad2deg = 180.0 / M_PI; From fa7f760a7b1700237d11b25ebe14559564edf827 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 15 Jun 2022 12:04:07 +0100 Subject: [PATCH 2/9] Tools: Improve error message --- tools/grib_get_data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/grib_get_data.c b/tools/grib_get_data.c index b5aadd581..682d7764b 100644 --- a/tools/grib_get_data.c +++ b/tools/grib_get_data.c @@ -136,7 +136,9 @@ int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h) /* Do a very basic sanity check */ const char* str = grib_options_get_option("L:"); if (string_count_char(str, '%') != 2) { - fprintf(stderr, "ERROR: Invalid lats/lons format option \"%s\".\nThe default is: \"%s\"\n", + fprintf(stderr, "ERROR: Invalid lats/lons format option \"%s\".\n" + " The default is: \"%s\"." + " For higher precision, try: \"%%12.6f%%12.6f\"\n", str, default_format_latlons); exit(1); } From b697f66b2efeafa942761ae506818523c4402289 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 15 Jun 2022 18:21:28 +0100 Subject: [PATCH 3/9] ECC-1405: Add new function: codes_handle_new_from_samples --- examples/C/new_sample.c | 8 +++---- src/eccodes.h | 11 +++++++++ src/eccodes_prototypes.h | 2 ++ src/grib_handle.c | 23 ++++++++++++++++++ src/grib_templates.c | 51 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/examples/C/new_sample.c b/examples/C/new_sample.c index 50fabf02f..0e483c472 100644 --- a/examples/C/new_sample.c +++ b/examples/C/new_sample.c @@ -25,7 +25,8 @@ int main(int argc, char** argv) exit(1); } - h = codes_grib_handle_new_from_samples(NULL, "GRIB2"); + /* h = codes_grib_handle_new_from_samples(NULL, "GRIB2"); */ + h = codes_handle_new_from_samples(NULL, "GRIB2"); if (!h) { fprintf(stderr, "Cannot create grib handle\n"); return 1; @@ -363,10 +364,7 @@ int main(int argc, char** argv) CODES_CHECK(codes_set_double_array(h, "values", vdouble, size), 0); free(vdouble); - CODES_CHECK(codes_set_long(h, "dirty_statistics", 1), 0); - CODES_CHECK(codes_set_long(h, "changeDecimalPrecision", 0), 0); - CODES_CHECK(codes_set_long(h, "decimalPrecision", 0), 0); - CODES_CHECK(codes_set_long(h, "setBitsPerValue", 0), 0); + /* Save the message */ f = fopen(argv[1], "wb"); diff --git a/src/eccodes.h b/src/eccodes.h index 76127cd06..08cf54587 100644 --- a/src/eccodes.h +++ b/src/eccodes.h @@ -477,6 +477,17 @@ codes_handle* codes_grib_handle_new_from_samples(codes_context* c, const char* s */ codes_handle* codes_bufr_handle_new_from_samples(codes_context* c, const char* sample_name); +/** + * Create a handle from a file contained in a samples directory. + * The samples file can be GRIB, BUFR etc. Its type will be determined at runtime. + * 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 + * @return the new handle, NULL if the resource is invalid or a problem is encountered + */ +codes_handle* codes_handle_new_from_samples(codes_context* c, const char* sample_name); + /** * Clone an existing handle using the context of the original handle, diff --git a/src/eccodes_prototypes.h b/src/eccodes_prototypes.h index 4844843bc..88452d227 100644 --- a/src/eccodes_prototypes.h +++ b/src/eccodes_prototypes.h @@ -1025,6 +1025,7 @@ void grib_empty_section(grib_context* c, grib_section* b); void grib_section_delete(grib_context* c, grib_section* b); int grib_handle_delete(grib_handle* h); grib_handle* grib_new_handle(grib_context* c); +grib_handle* codes_handle_new_from_samples(grib_context* c, const char* name); grib_handle* grib_handle_new_from_samples(grib_context* c, const char* name); grib_handle* codes_bufr_handle_new_from_samples(grib_context* c, const char* name); int grib_write_message(const grib_handle* h, const char* file, const char* mode); @@ -1187,6 +1188,7 @@ long grib_get_decimal_scale_fact(double max, double min, long bpval, long binary /* grib_templates.c */ /*grib_handle *grib_internal_sample(grib_context *c, const char *name);*/ +grib_handle* codes_external_template(grib_context* c, const char* name); grib_handle* grib_external_template(grib_context* c, const char* name); grib_handle* bufr_external_template(grib_context* c, const char* name); char* get_external_template_path(grib_context* c, const char* name); diff --git a/src/grib_handle.c b/src/grib_handle.c index 6ed1a683a..8437d5bc2 100644 --- a/src/grib_handle.c +++ b/src/grib_handle.c @@ -248,6 +248,29 @@ static grib_handle* grib_handle_create(grib_handle* gl, grib_context* c, const v return gl; } +grib_handle* codes_handle_new_from_samples(grib_context* c, const char* name) +{ + grib_handle* g = 0; + if (c == NULL) + c = grib_context_get_default(); + grib_context_set_handle_file_count(c, 0); + grib_context_set_handle_total_count(c, 0); + + if (c->debug) { + fprintf(stderr, "ECCODES DEBUG codes_handle_new_from_samples '%s'\n", name); + } + + g = codes_external_template(c, name); + if (!g) + grib_context_log(c, GRIB_LOG_ERROR, + "Unable to load sample file '%s.tmpl'\n" + " from %s\n" + " (ecCodes Version=%s)", + name, c->grib_samples_path, ECCODES_VERSION_STR); + + return g; +} + grib_handle* grib_handle_new_from_samples(grib_context* c, const char* name) { grib_handle* g = 0; diff --git a/src/grib_templates.c b/src/grib_templates.c index 5ff8e859f..fc0cb835f 100644 --- a/src/grib_templates.c +++ b/src/grib_templates.c @@ -70,6 +70,24 @@ static grib_handle* try_product_template(grib_context* c, ProductKind product_ki grib_context_log(c, GRIB_LOG_PERROR, "cannot open %s", path); return NULL; } + if (product_kind == PRODUCT_ANY) + { + /* Determine the product kind from sample file */ + char* mesg = NULL; + size_t size = 0; + off_t offset = 0; + mesg = wmo_read_any_from_file_malloc(f, 0, &size, &offset, &err); + Assert(size > 4); + if (strncmp(mesg, "GRIB", 4) == 0 || strncmp(mesg, "DIAG", 4) == 0 || strncmp(mesg, "BUDG", 4) == 0) { + product_kind = PRODUCT_GRIB; + } else if (strncmp(mesg, "BUFR", 4) == 0) { + product_kind = PRODUCT_BUFR; + } else { + grib_context_log(c, GRIB_LOG_ERROR, "Could not determine product kind"); + } + grib_context_free(c, mesg); + rewind(f); + } if (product_kind == PRODUCT_BUFR) { g = codes_bufr_handle_new_from_file(c, f, &err); } else { @@ -77,7 +95,7 @@ static grib_handle* try_product_template(grib_context* c, ProductKind product_ki g = grib_handle_new_from_file(c, f, &err); } if (!g) { - grib_context_log(c, GRIB_LOG_ERROR, "cannot create handle from %s", path); + grib_context_log(c, GRIB_LOG_ERROR, "Cannot create handle from %s", path); } fclose(f); } @@ -100,6 +118,37 @@ static char* try_template_path(grib_context* c, const char* dir, const char* nam return NULL; } +/* TODO: The following functions should be renamed/combined: + * codes_external_template + * grib_external_template + * bufr_external_template +*/ +grib_handle* codes_external_template(grib_context* c, const char* name) +{ + const char* base = c->grib_samples_path; + char buffer[1024]; + char* p = buffer; + grib_handle* g = NULL; + + if (!base) + return NULL; + + while (*base) { + if (*base == ECC_PATH_DELIMITER_CHAR) { + *p = 0; + g = try_product_template(c, PRODUCT_ANY, buffer, name); + if (g) + return g; + p = buffer; + base++; /*advance past delimiter*/ + } + *p++ = *base++; + } + + *p = 0; + return g = try_product_template(c, PRODUCT_ANY, buffer, name); +} + grib_handle* grib_external_template(grib_context* c, const char* name) { const char* base = c->grib_samples_path; From 1aa377fde14aabe50027fe4f4102a92e7e9af0b5 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 15 Jun 2022 19:17:59 +0100 Subject: [PATCH 4/9] ECC-1405: Cleanup --- src/eccodes_prototypes.h | 5 +-- src/grib_handle.c | 10 ++--- src/grib_templates.c | 83 ++++++++-------------------------------- 3 files changed, 20 insertions(+), 78 deletions(-) diff --git a/src/eccodes_prototypes.h b/src/eccodes_prototypes.h index 88452d227..93910d5f7 100644 --- a/src/eccodes_prototypes.h +++ b/src/eccodes_prototypes.h @@ -1187,10 +1187,7 @@ long grib_get_bits_per_value(double max, double min, long binary_scale_factor); long grib_get_decimal_scale_fact(double max, double min, long bpval, long binary_scale); /* grib_templates.c */ -/*grib_handle *grib_internal_sample(grib_context *c, const char *name);*/ -grib_handle* codes_external_template(grib_context* c, const char* name); -grib_handle* grib_external_template(grib_context* c, const char* name); -grib_handle* bufr_external_template(grib_context* c, const char* name); +grib_handle* codes_external_template(grib_context* c, ProductKind product_kind, const char* name); char* get_external_template_path(grib_context* c, const char* name); /* grib_dependency.c */ diff --git a/src/grib_handle.c b/src/grib_handle.c index 8437d5bc2..84c152cc5 100644 --- a/src/grib_handle.c +++ b/src/grib_handle.c @@ -260,7 +260,7 @@ grib_handle* codes_handle_new_from_samples(grib_context* c, const char* name) fprintf(stderr, "ECCODES DEBUG codes_handle_new_from_samples '%s'\n", name); } - g = codes_external_template(c, name); + g = codes_external_template(c, PRODUCT_ANY, name); if (!g) grib_context_log(c, GRIB_LOG_ERROR, "Unable to load sample file '%s.tmpl'\n" @@ -287,7 +287,7 @@ grib_handle* grib_handle_new_from_samples(grib_context* c, const char* name) fprintf(stderr, "ECCODES DEBUG grib_handle_new_from_samples '%s'\n", name); } - g = grib_external_template(c, name); + g = codes_external_template(c, PRODUCT_GRIB, name); if (!g) grib_context_log(c, GRIB_LOG_ERROR, "Unable to load GRIB sample file '%s.tmpl'\n" @@ -306,15 +306,11 @@ grib_handle* codes_bufr_handle_new_from_samples(grib_context* c, const char* nam grib_context_set_handle_file_count(c, 0); grib_context_set_handle_total_count(c, 0); - /* - * g = grib_internal_sample(c,name); - * if(g) return g; - */ if (c->debug) { fprintf(stderr, "ECCODES DEBUG bufr_handle_new_from_samples '%s'\n", name); } - g = bufr_external_template(c, name); + g = codes_external_template(c, PRODUCT_BUFR, name); if (!g) grib_context_log(c, GRIB_LOG_ERROR, "Unable to load BUFR sample file '%s.tmpl'\n" diff --git a/src/grib_templates.c b/src/grib_templates.c index fc0cb835f..7252c5999 100644 --- a/src/grib_templates.c +++ b/src/grib_templates.c @@ -49,6 +49,7 @@ grib_handle* grib_internal_sample(grib_context* c,const char* name) #define ECC_PATH_DELIMITER_CHAR ':' #endif +/* if product_kind is PRODUCT_ANY, the type of sample file is determined at runtime */ static grib_handle* try_product_template(grib_context* c, ProductKind product_kind, const char* dir, const char* name) { char path[1024]; @@ -77,21 +78,26 @@ static grib_handle* try_product_template(grib_context* c, ProductKind product_ki size_t size = 0; off_t offset = 0; mesg = wmo_read_any_from_file_malloc(f, 0, &size, &offset, &err); - Assert(size > 4); - if (strncmp(mesg, "GRIB", 4) == 0 || strncmp(mesg, "DIAG", 4) == 0 || strncmp(mesg, "BUDG", 4) == 0) { - product_kind = PRODUCT_GRIB; - } else if (strncmp(mesg, "BUFR", 4) == 0) { - product_kind = PRODUCT_BUFR; + if (mesg && !err) { + Assert(size > 4); + if (strncmp(mesg, "GRIB", 4) == 0 || strncmp(mesg, "DIAG", 4) == 0 || strncmp(mesg, "BUDG", 4) == 0) { + product_kind = PRODUCT_GRIB; + } else if (strncmp(mesg, "BUFR", 4) == 0) { + product_kind = PRODUCT_BUFR; + } else { + grib_context_log(c, GRIB_LOG_ERROR, "Could not determine product kind"); + } + grib_context_free(c, mesg); + rewind(f); } else { grib_context_log(c, GRIB_LOG_ERROR, "Could not determine product kind"); } - grib_context_free(c, mesg); - rewind(f); } if (product_kind == PRODUCT_BUFR) { g = codes_bufr_handle_new_from_file(c, f, &err); } else { /* Note: Pseudo GRIBs like DIAG and BUDG also come here */ + DebugAssert(product_kind == PRODUCT_GRIB); g = grib_handle_new_from_file(c, f, &err); } if (!g) { @@ -118,12 +124,7 @@ static char* try_template_path(grib_context* c, const char* dir, const char* nam return NULL; } -/* TODO: The following functions should be renamed/combined: - * codes_external_template - * grib_external_template - * bufr_external_template -*/ -grib_handle* codes_external_template(grib_context* c, const char* name) +grib_handle* codes_external_template(grib_context* c, ProductKind product_kind, const char* name) { const char* base = c->grib_samples_path; char buffer[1024]; @@ -136,7 +137,7 @@ grib_handle* codes_external_template(grib_context* c, const char* name) while (*base) { if (*base == ECC_PATH_DELIMITER_CHAR) { *p = 0; - g = try_product_template(c, PRODUCT_ANY, buffer, name); + g = try_product_template(c, product_kind, buffer, name); if (g) return g; p = buffer; @@ -146,59 +147,7 @@ grib_handle* codes_external_template(grib_context* c, const char* name) } *p = 0; - return g = try_product_template(c, PRODUCT_ANY, buffer, name); -} - -grib_handle* grib_external_template(grib_context* c, const char* name) -{ - const char* base = c->grib_samples_path; - char buffer[1024]; - char* p = buffer; - grib_handle* g = NULL; - - if (!base) - return NULL; - - while (*base) { - if (*base == ECC_PATH_DELIMITER_CHAR) { - *p = 0; - g = try_product_template(c, PRODUCT_GRIB, buffer, name); - if (g) - return g; - p = buffer; - base++; /*advance past delimiter*/ - } - *p++ = *base++; - } - - *p = 0; - return g = try_product_template(c, PRODUCT_GRIB, buffer, name); -} - -grib_handle* bufr_external_template(grib_context* c, const char* name) -{ - const char* base = c->grib_samples_path; - char buffer[1024]; - char* p = buffer; - grib_handle* g = NULL; - - if (!base) - return NULL; - - while (*base) { - if (*base == ECC_PATH_DELIMITER_CHAR) { - *p = 0; - g = try_product_template(c, PRODUCT_BUFR, buffer, name); - if (g) - return g; - p = buffer; - base++; /*advance past delimiter*/ - } - *p++ = *base++; - } - - *p = 0; - g = try_product_template(c, PRODUCT_BUFR, buffer, name); + g = try_product_template(c, product_kind, buffer, name); return g; } From 357f666f3de16a2ecce01cc411e6d0a67b87f435 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 16 Jun 2022 11:07:06 +0100 Subject: [PATCH 5/9] ECC-1405: Tests --- tests/CMakeLists.txt | 2 + tests/codes_new_from_samples.c | 66 +++++++++++++++++++++++++++++++++ tests/codes_new_from_samples.sh | 13 +++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/codes_new_from_samples.c create mode 100755 tests/codes_new_from_samples.sh diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bbaa944af..98a13d72e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,6 +36,7 @@ list(APPEND test_bins bufr_extract_headers extract_offsets bufr_check_descriptors + codes_new_from_samples grib_sh_ieee64 grib_ieee grib_set_bytes @@ -245,6 +246,7 @@ if( HAVE_BUILD_TOOLS ) grib_statistics grib_tigge_check read_any + codes_new_from_samples grib_dump grib_dump_debug grib_dump_json diff --git a/tests/codes_new_from_samples.c b/tests/codes_new_from_samples.c new file mode 100644 index 000000000..634c9837a --- /dev/null +++ b/tests/codes_new_from_samples.c @@ -0,0 +1,66 @@ +/* + * (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. + */ + +#include +#include "eccodes.h" + +typedef struct sample_t { + const char* sample_name; + ProductKind expected_kind; +} sample_t; + +static sample_t samples[] = { + {"GRIB1", PRODUCT_GRIB}, + {"GRIB2", PRODUCT_GRIB}, + {"reduced_gg_pl_256_grib1", PRODUCT_GRIB}, + {"reduced_gg_pl_256_grib2", PRODUCT_GRIB}, + {"sh_ml_grib1.tmpl", PRODUCT_GRIB}, + {"sh_ml_grib2.tmpl", PRODUCT_GRIB}, + + {"diag", PRODUCT_GRIB}, /* pseudo GRIBs */ + {"budg", PRODUCT_GRIB}, + + {"BUFR4_local_satellite", PRODUCT_BUFR}, + {"BUFR4_local", PRODUCT_BUFR}, + {"BUFR4", PRODUCT_BUFR}, + {"BUFR3", PRODUCT_BUFR} +}; + +#define NUMBER(a) sizeof(a)/sizeof(a[0]) + +int main(int argc, char** argv) +{ + codes_handle* h = NULL; + size_t i = 0; + + for (i=0; i Date: Thu, 16 Jun 2022 11:33:17 +0100 Subject: [PATCH 6/9] ECC-1405: Tests --- tests/codes_new_from_samples.c | 45 +++++++++++++++------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/tests/codes_new_from_samples.c b/tests/codes_new_from_samples.c index 634c9837a..642e90f8d 100644 --- a/tests/codes_new_from_samples.c +++ b/tests/codes_new_from_samples.c @@ -9,56 +9,51 @@ */ #include -#include "eccodes.h" +#include "grib_api_internal.h" typedef struct sample_t { const char* sample_name; + const char* expected_ID; ProductKind expected_kind; } sample_t; static sample_t samples[] = { - {"GRIB1", PRODUCT_GRIB}, - {"GRIB2", PRODUCT_GRIB}, - {"reduced_gg_pl_256_grib1", PRODUCT_GRIB}, - {"reduced_gg_pl_256_grib2", PRODUCT_GRIB}, - {"sh_ml_grib1.tmpl", PRODUCT_GRIB}, - {"sh_ml_grib2.tmpl", PRODUCT_GRIB}, + {"GRIB1", "GRIB", PRODUCT_GRIB}, + {"GRIB2", "GRIB", PRODUCT_GRIB}, + {"reduced_gg_pl_256_grib1", "GRIB", PRODUCT_GRIB}, + {"reduced_gg_pl_256_grib2", "GRIB", PRODUCT_GRIB}, + {"sh_ml_grib1.tmpl", "GRIB", PRODUCT_GRIB}, + {"sh_ml_grib2.tmpl", "GRIB", PRODUCT_GRIB}, - {"diag", PRODUCT_GRIB}, /* pseudo GRIBs */ - {"budg", PRODUCT_GRIB}, + {"diag", "DIAG", PRODUCT_GRIB}, /* pseudo GRIBs */ + {"budg", "BUDG", PRODUCT_GRIB}, - {"BUFR4_local_satellite", PRODUCT_BUFR}, - {"BUFR4_local", PRODUCT_BUFR}, - {"BUFR4", PRODUCT_BUFR}, - {"BUFR3", PRODUCT_BUFR} + {"BUFR4_local_satellite", "BUFR", PRODUCT_BUFR}, + {"BUFR4_local", "BUFR", PRODUCT_BUFR}, + {"BUFR4", "BUFR", PRODUCT_BUFR}, + {"BUFR3", "BUFR", PRODUCT_BUFR} }; #define NUMBER(a) sizeof(a)/sizeof(a[0]) int main(int argc, char** argv) { - codes_handle* h = NULL; + grib_handle* h = NULL; size_t i = 0; for (i=0; iproduct_kind); - CODES_CHECK(codes_get_string(h, "kindOfProduct", kindstr, &len), 0); - if (samples[i].expected_kind == PRODUCT_GRIB) { - assert( strcmp(kindstr, "GRIB")==0 || - strcmp(kindstr, "DIAG")==0 || - strcmp(kindstr, "BUDG")==0 ); - } - if (samples[i].expected_kind == PRODUCT_BUFR) { - assert( strcmp(kindstr, "BUFR")==0 ); - } - codes_handle_delete(h); + GRIB_CHECK(grib_get_string(h, "identifier", identifier, &len), 0); + assert( strcmp(samples[i].expected_ID, identifier) == 0 ); + grib_handle_delete(h); } fprintf(stderr,"All done\n"); From 1e456b745fc1b50d74451ad48935a8de71b13cb0 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 16 Jun 2022 20:16:00 +0100 Subject: [PATCH 7/9] ECC-1406: GRIB: grib_ls -l reports last grid point is out of area --- src/grib_iterator_class_latlon.c | 4 +++ src/grib_iterator_class_regular.c | 4 +++ tests/CMakeLists.txt | 1 + tests/grib_ecc-1406.sh | 49 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100755 tests/grib_ecc-1406.sh diff --git a/src/grib_iterator_class_latlon.c b/src/grib_iterator_class_latlon.c index 246969cbf..deab88802 100644 --- a/src/grib_iterator_class_latlon.c +++ b/src/grib_iterator_class_latlon.c @@ -211,6 +211,10 @@ static int init(grib_iterator* iter, grib_handle* h, grib_arguments* args) self->las[lai] = lat1; lat1 -= jdir; } + /* ECC-1406: Due to rounding, errors can accumulate. + * So we ensure the last latitude is latitudeOfLastGridPointInDegrees + */ + self->las[self->Nj-1] = lat2; iter->e = -1; return err; diff --git a/src/grib_iterator_class_regular.c b/src/grib_iterator_class_regular.c index ef988b9c3..d4e5c652b 100644 --- a/src/grib_iterator_class_regular.c +++ b/src/grib_iterator_class_regular.c @@ -220,6 +220,10 @@ static int init(grib_iterator* i, grib_handle* h, grib_arguments* args) self->los[loi] = lon1; lon1 += idir; } + /* ECC-1406: Due to rounding, errors can accumulate. + * So we ensure the last longitude is longitudeOfLastGridPointInDegrees + */ + self->los[Ni-1] = lon2; return ret; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 98a13d72e..5f915d6e5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -96,6 +96,7 @@ if( HAVE_BUILD_TOOLS ) grib_ecc-1315 grib_ecc-1322 grib_ecc-1319 + grib_ecc-1406 bufr_ecc-1028 bufr_ecc-1195 bufr_ecc-1259 diff --git a/tests/grib_ecc-1406.sh b/tests/grib_ecc-1406.sh new file mode 100755 index 000000000..ace8e0031 --- /dev/null +++ b/tests/grib_ecc-1406.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# (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. +# + +. ./include.ctest.sh +set -u +REDIRECT=/dev/null +label="grib_ecc-1406_test" + +tempGrib=temp.$label.grib +tempFilt=temp.${label}.filt +tempOut=temp.${label}.txt + +sample2="$samp_dir/GRIB2.tmpl" + +cat > $tempFilt < $tempOut + +grep -q "Grid Point chosen #1 index=5016590" $tempOut +grep -q "grid_simple 42" $tempOut + +${tools_dir}/grib_ls -j -l 37.5,16.0,1 $tempGrib > $tempOut +grep -q 'latitude" : 37.5, "longitude" : 16, "distance" : 0,.*"value" : 42 ,' $tempOut + +rm -f $tempGrib $tempFilt $tempOut From 805e2aa75ebcee007ec3eff11deff12367d329c5 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 16 Jun 2022 22:56:09 +0100 Subject: [PATCH 8/9] Fix metabuilder compilation --- src/grib_templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grib_templates.c b/src/grib_templates.c index 7252c5999..b179dd987 100644 --- a/src/grib_templates.c +++ b/src/grib_templates.c @@ -77,7 +77,7 @@ static grib_handle* try_product_template(grib_context* c, ProductKind product_ki char* mesg = NULL; size_t size = 0; off_t offset = 0; - mesg = wmo_read_any_from_file_malloc(f, 0, &size, &offset, &err); + mesg = (char*)wmo_read_any_from_file_malloc(f, 0, &size, &offset, &err); if (mesg && !err) { Assert(size > 4); if (strncmp(mesg, "GRIB", 4) == 0 || strncmp(mesg, "DIAG", 4) == 0 || strncmp(mesg, "BUDG", 4) == 0) { From d29e94822f008c2b5c3a5851dd541e65b56baff8 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 16 Jun 2022 22:58:15 +0100 Subject: [PATCH 9/9] Nearest: Assertion --- src/grib_nearest_class_regular.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grib_nearest_class_regular.c b/src/grib_nearest_class_regular.c index 6c8b44211..4c0e85bdf 100644 --- a/src/grib_nearest_class_regular.c +++ b/src/grib_nearest_class_regular.c @@ -323,8 +323,8 @@ static int find(grib_nearest* nearest, grib_handle* h, return ret; } while (grib_iterator_next(iter, &lat, &lon, &dummy)) { - if (olat != lat) { - Assert(ilat < self->lats_count); + if (ilat < self->lats_count && olat != lat) { + /* Assert(ilat < self->lats_count); */ self->lats[ilat++] = lat; olat = lat; }