mirror of https://github.com/ecmwf/eccodes.git
Merge branch 'develop' into feature/ECC-1403-Nearest-Part2
This commit is contained in:
commit
866593c4bb
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1026,6 +1026,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,9 +1188,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* 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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, PRODUCT_ANY, 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;
|
||||
|
@ -264,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"
|
||||
|
@ -283,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"
|
||||
|
|
|
@ -210,6 +210,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;
|
||||
|
|
|
@ -219,6 +219,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;
|
||||
}
|
||||
|
|
|
@ -322,8 +322,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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
@ -70,14 +71,37 @@ 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 = (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) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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,7 +124,7 @@ static char* try_template_path(grib_context* c, const char* dir, const char* nam
|
|||
return NULL;
|
||||
}
|
||||
|
||||
grib_handle* grib_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];
|
||||
|
@ -113,7 +137,7 @@ grib_handle* grib_external_template(grib_context* c, const char* name)
|
|||
while (*base) {
|
||||
if (*base == ECC_PATH_DELIMITER_CHAR) {
|
||||
*p = 0;
|
||||
g = try_product_template(c, PRODUCT_GRIB, buffer, name);
|
||||
g = try_product_template(c, product_kind, buffer, name);
|
||||
if (g)
|
||||
return g;
|
||||
p = buffer;
|
||||
|
@ -123,33 +147,7 @@ grib_handle* grib_external_template(grib_context* c, const char* name)
|
|||
}
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -95,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
|
||||
|
@ -245,6 +247,7 @@ if( HAVE_BUILD_TOOLS )
|
|||
grib_statistics
|
||||
grib_tigge_check
|
||||
read_any
|
||||
codes_new_from_samples
|
||||
grib_dump
|
||||
grib_dump_debug
|
||||
grib_dump_json
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* (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 <assert.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", "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", "DIAG", PRODUCT_GRIB}, /* pseudo GRIBs */
|
||||
{"budg", "BUDG", PRODUCT_GRIB},
|
||||
|
||||
{"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)
|
||||
{
|
||||
grib_handle* h = NULL;
|
||||
size_t i = 0;
|
||||
|
||||
for (i=0; i<NUMBER(samples); ++i) {
|
||||
const char* name = samples[i].sample_name;
|
||||
char identifier[254] = {0,};
|
||||
size_t len = 254;
|
||||
|
||||
printf("Testing codes_handle_new_from_samples on %s\n", name);
|
||||
h = codes_handle_new_from_samples(0, name);
|
||||
assert(h);
|
||||
assert(samples[i].expected_kind == h->product_kind);
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#!/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
|
||||
|
||||
$EXEC ${test_dir}/codes_new_from_samples
|
|
@ -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 <<EOF
|
||||
set numberOfDataPoints = 5016591;
|
||||
set numberOfValues = 5016591;
|
||||
set Ni = 2801;
|
||||
set Nj = 1791;
|
||||
set latitudeOfFirstGridPoint = 55400000;
|
||||
set longitudeOfFirstGridPoint = 348000000;
|
||||
set latitudeOfLastGridPoint = 37500000;
|
||||
set longitudeOfLastGridPoint = 16000000;
|
||||
set iDirectionIncrement = 10000;
|
||||
set jDirectionIncrement = 10000;
|
||||
|
||||
meta lastVal element(values, numberOfValues - 1);
|
||||
set lastVal = 42;
|
||||
|
||||
write;
|
||||
EOF
|
||||
|
||||
${tools_dir}/grib_filter -o $tempGrib $tempFilt $sample2
|
||||
${tools_dir}/grib_ls -l 37.5,16.0,1 $tempGrib > $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
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue