mirror of https://github.com/ecmwf/eccodes.git
Merge branch 'develop' into hotfix/ECC-1602-performance-optim-ccsds
This commit is contained in:
commit
4533d073e9
6
INSTALL
6
INSTALL
|
@ -3,11 +3,9 @@ How to build and install ecCodes library/tools
|
|||
|
||||
Building and installation has been tested on several platforms and with several compilers.
|
||||
However for some platforms modifications to the installation engine may be required.
|
||||
If you encounter any problems during the installation procedure please send an e-mail
|
||||
with your problem to:
|
||||
|
||||
Software.Support@ecmwf.int
|
||||
If you encounter any problems during the installation procedure, please visit our Support Portal:
|
||||
|
||||
https://support.ecmwf.int
|
||||
|
||||
Installation using CMake
|
||||
------------------------
|
||||
|
|
|
@ -67,9 +67,9 @@ To add the Python3 bindings, use pip3 install from PyPI as follows:
|
|||
For more details, please see:
|
||||
https://confluence.ecmwf.int/display/ECC/ecCodes+installation
|
||||
|
||||
If you encounter any problems please send an e-mail with your problem to:
|
||||
If you encounter any problems please visit our Support Portal:
|
||||
|
||||
Software.Support@ecmwf.int
|
||||
https://support.ecmwf.int
|
||||
|
||||
|
||||
|
||||
|
|
109
src/bufr_util.cc
109
src/bufr_util.cc
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include "grib_api_internal.h"
|
||||
|
||||
/* Return the rank of the key using list of keys (For BUFR keys) */
|
||||
/* The argument 'keys' is an input as well as output from each call */
|
||||
// Return the rank of the key using list of keys (For BUFR keys)
|
||||
// The argument 'keys' is an input as well as output from each call
|
||||
int compute_bufr_key_rank(grib_handle* h, grib_string_list* keys, const char* key)
|
||||
{
|
||||
grib_string_list* next = keys;
|
||||
|
@ -43,11 +43,11 @@ int compute_bufr_key_rank(grib_handle* h, grib_string_list* keys, const char* ke
|
|||
next->count++;
|
||||
theRank = next->count;
|
||||
if (theRank == 1) {
|
||||
/* If the count is 1 it could mean two things: */
|
||||
/* This is the first instance of the key and there is another one */
|
||||
/* This is the first and only instance of the key */
|
||||
/* So we check if there is a second one of this key, */
|
||||
/* If not, then rank is zero i.e. this is the only instance */
|
||||
// If the count is 1 it could mean two things:
|
||||
// This is the first instance of the key and there is another one
|
||||
// This is the first and only instance of the key
|
||||
// So we check if there is a second one of this key,
|
||||
// If not, then rank is zero i.e. this is the only instance
|
||||
size_t slen = strlen(key) + 5;
|
||||
char* s = (char*)grib_context_malloc_clear(c, slen);
|
||||
snprintf(s, slen, "#2#%s", key);
|
||||
|
@ -77,14 +77,13 @@ char** codes_bufr_copy_data_return_copied_keys(grib_handle* hin, grib_handle* ho
|
|||
|
||||
while (codes_bufr_keys_iterator_next(kiter)) {
|
||||
char* name = codes_bufr_keys_iterator_get_name(kiter);
|
||||
/* if the copy fails we want to keep copying without any errors.
|
||||
This is because the copy can be between structures that are not
|
||||
identical and we want to copy what can be copied and skip what
|
||||
cannot be copied because is not in the output handle
|
||||
*/
|
||||
// if the copy fails we want to keep copying without any errors.
|
||||
// This is because the copy can be between structures that are not
|
||||
// identical and we want to copy what can be copied and skip what
|
||||
// cannot be copied because is not in the output handle
|
||||
*err = codes_copy_key(hin, hout, name, 0);
|
||||
if (*err == 0) {
|
||||
/* 'name' will be freed when we call codes_bufr_keys_iterator_delete so copy */
|
||||
// 'name' will be freed when we call codes_bufr_keys_iterator_delete so copy
|
||||
char* copied_name = strdup(name);
|
||||
k = grib_sarray_push(hin->context, k, copied_name);
|
||||
}
|
||||
|
@ -93,7 +92,7 @@ char** codes_bufr_copy_data_return_copied_keys(grib_handle* hin, grib_handle* ho
|
|||
keys = grib_sarray_get_array(hin->context, k);
|
||||
grib_sarray_delete(hin->context, k);
|
||||
if (*nkeys > 0) {
|
||||
/* Do the pack if something was copied */
|
||||
// Do the pack if something was copied
|
||||
*err = grib_set_long(hout, "pack", 1);
|
||||
}
|
||||
codes_bufr_keys_iterator_delete(kiter);
|
||||
|
@ -116,18 +115,17 @@ int codes_bufr_copy_data(grib_handle* hin, grib_handle* hout)
|
|||
|
||||
while (codes_bufr_keys_iterator_next(kiter)) {
|
||||
char* name = codes_bufr_keys_iterator_get_name(kiter);
|
||||
/* if the copy fails we want to keep copying without any error messages.
|
||||
This is because the copy can be between structures that are not
|
||||
identical and we want to copy what can be copied and skip what
|
||||
cannot be copied because is not in the output handle
|
||||
*/
|
||||
// if the copy fails we want to keep copying without any error messages.
|
||||
// This is because the copy can be between structures that are not
|
||||
// identical and we want to copy what can be copied and skip what
|
||||
// cannot be copied because is not in the output handle
|
||||
err = codes_copy_key(hin, hout, name, GRIB_TYPE_UNDEFINED);
|
||||
if (err == 0)
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
if (nkeys > 0) {
|
||||
/* Do the pack if something was copied */
|
||||
// Do the pack if something was copied
|
||||
err = grib_set_long(hout, "pack", 1);
|
||||
}
|
||||
|
||||
|
@ -135,7 +133,7 @@ int codes_bufr_copy_data(grib_handle* hin, grib_handle* hout)
|
|||
return err;
|
||||
}
|
||||
|
||||
#define BUFR_SECTION0_LEN 8 /* BUFR section 0 is always 8 bytes long */
|
||||
#define BUFR_SECTION0_LEN 8 // BUFR section 0 is always 8 bytes long
|
||||
static int bufr_extract_edition(const void* message, long* edition)
|
||||
{
|
||||
const long nbits_edition = 8;
|
||||
|
@ -145,7 +143,7 @@ static int bufr_extract_edition(const void* message, long* edition)
|
|||
*edition = (long)grib_decode_unsigned_long(pMessage, &pos_edition, nbits_edition);
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
/* The ECMWF BUFR local use section */
|
||||
// The ECMWF BUFR local use section
|
||||
static int bufr_decode_rdb_keys(const void* message, long offset_section2, codes_bufr_header* hdr)
|
||||
{
|
||||
const unsigned char* pMessage = (const unsigned char*)message;
|
||||
|
@ -181,7 +179,7 @@ static int bufr_decode_rdb_keys(const void* message, long offset_section2, codes
|
|||
hdr->localMinute = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
hdr->localSecond = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
|
||||
/* rdbtime */
|
||||
// rdbtime
|
||||
p = (unsigned char*)message + offset_rdbtime;
|
||||
start = 0;
|
||||
hdr->rdbtimeDay = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
|
@ -189,7 +187,7 @@ static int bufr_decode_rdb_keys(const void* message, long offset_section2, codes
|
|||
hdr->rdbtimeMinute = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
hdr->rdbtimeSecond = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
|
||||
/* rectime */
|
||||
// rectime
|
||||
p = (unsigned char*)message + offset_rectime;
|
||||
start = 0;
|
||||
hdr->rectimeDay = (long)grib_decode_unsigned_long(p, &start, 6);
|
||||
|
@ -206,16 +204,16 @@ static int bufr_decode_rdb_keys(const void* message, long offset_section2, codes
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
#define IDENT_LEN 9 /* 8 chars plus the final 0 terminator */
|
||||
#define IDENT_LEN 9 // 8 chars plus the final 0 terminator
|
||||
|
||||
/* The ECMWF BUFR local use section */
|
||||
// The ECMWF BUFR local use section
|
||||
static int bufr_decode_extra_rdb_keys(const void* message, long offset_section2, codes_bufr_header* hdr)
|
||||
{
|
||||
bool isSatelliteType = false;
|
||||
long start = 0;
|
||||
const long offset_keyData = offset_section2 + 6;
|
||||
const long offset_keyMore = offset_section2 + 19; /* 8 bytes long */
|
||||
const long offset_keySat = offset_section2 + 27; /* 9 bytes long */
|
||||
const long offset_keyMore = offset_section2 + 19; // 8 bytes long
|
||||
const long offset_keySat = offset_section2 + 27; // 9 bytes long
|
||||
|
||||
unsigned char* pKeyData = (unsigned char*)message + offset_keyData;
|
||||
char* pKeyMore = (char*)message + offset_keyMore;
|
||||
|
@ -233,7 +231,7 @@ static int bufr_decode_extra_rdb_keys(const void* message, long offset_section2,
|
|||
}
|
||||
|
||||
if (hdr->isSatellite) {
|
||||
unsigned char* pKeyMoreLong = (unsigned char*)message + offset_keyMore; /* as an integer */
|
||||
unsigned char* pKeyMoreLong = (unsigned char*)message + offset_keyMore; // as an integer
|
||||
unsigned char* pKeySat = (unsigned char*)message + offset_keySat;
|
||||
unsigned long lValue = 0;
|
||||
start = 40;
|
||||
|
@ -277,13 +275,13 @@ static int bufr_decode_extra_rdb_keys(const void* message, long offset_section2,
|
|||
lValue = grib_decode_unsigned_long(pKeyData, &start, 26);
|
||||
hdr->localLongitude = (lValue - 18000000.0) / 100000.0;
|
||||
|
||||
/* interpret keyMore as a string. Copy to a temporary */
|
||||
// interpret keyMore as a string. Copy to a temporary
|
||||
for (i = 0; i < IDENT_LEN - 1; ++i) {
|
||||
temp[i] = *pKeyMore++;
|
||||
}
|
||||
temp[i] = '\0';
|
||||
pTemp = temp;
|
||||
string_lrtrim(&pTemp, 1, 1); /* Trim left and right */
|
||||
string_lrtrim(&pTemp, 1, 1); // Trim left and right
|
||||
strncpy(hdr->ident, pTemp, IDENT_LEN - 1);
|
||||
}
|
||||
|
||||
|
@ -331,7 +329,7 @@ static int bufr_decode_edition3(const void* message, codes_bufr_header* hdr)
|
|||
long nbits_localTablesVersionNumber = 1 * 8;
|
||||
long pos_localTablesVersionNumber = 19 * 8;
|
||||
|
||||
const long typicalCentury = 21; /* This century */
|
||||
const long typicalCentury = 21; // This century
|
||||
long typicalYearOfCentury = 0;
|
||||
long nbits_typicalYearOfCentury = 1 * 8;
|
||||
long pos_typicalYearOfCentury = 20 * 8;
|
||||
|
@ -352,11 +350,11 @@ static int bufr_decode_edition3(const void* message, codes_bufr_header* hdr)
|
|||
long offset_section2 = 0;
|
||||
long offset_section3 = 0;
|
||||
long nbits_numberOfSubsets = 2 * 8;
|
||||
long pos_numberOfSubsets = 0; /*depends on offset_section3*/
|
||||
long pos_numberOfSubsets = 0; //depends on offset_section3
|
||||
|
||||
unsigned long section3Flags;
|
||||
long nbits_section3Flags = 1 * 8;
|
||||
long pos_section3Flags = 0; /*depends on offset_section3*/
|
||||
long pos_section3Flags = 0; //depends on offset_section3
|
||||
|
||||
totalLength = grib_decode_unsigned_long(pMessage, &pos_totalLength, nbits_totalLength);
|
||||
if (totalLength != hdr->message_size) {
|
||||
|
@ -383,7 +381,7 @@ static int bufr_decode_edition3(const void* message, codes_bufr_header* hdr)
|
|||
hdr->typicalDate = hdr->typicalYear * 10000 + hdr->typicalMonth * 100 + hdr->typicalDay;
|
||||
hdr->typicalTime = hdr->typicalHour * 10000 + hdr->typicalMinute * 100 + hdr->typicalSecond;
|
||||
|
||||
offset_section2 = BUFR_SECTION0_LEN + section1Length; /*bytes*/
|
||||
offset_section2 = BUFR_SECTION0_LEN + section1Length; //bytes
|
||||
section2Length = 0;
|
||||
hdr->localSectionPresent = (section1Flags != 0);
|
||||
if (hdr->localSectionPresent) {
|
||||
|
@ -399,7 +397,7 @@ static int bufr_decode_edition3(const void* message, codes_bufr_header* hdr)
|
|||
}
|
||||
}
|
||||
|
||||
offset_section3 = BUFR_SECTION0_LEN + section1Length + section2Length; /*bytes*/
|
||||
offset_section3 = BUFR_SECTION0_LEN + section1Length + section2Length; //bytes
|
||||
pos_numberOfSubsets = (offset_section3 + 4) * 8;
|
||||
hdr->numberOfSubsets = grib_decode_unsigned_long(pMessage, &pos_numberOfSubsets, nbits_numberOfSubsets);
|
||||
|
||||
|
@ -459,7 +457,7 @@ static int bufr_decode_edition4(const void* message, codes_bufr_header* hdr)
|
|||
long nbits_localTablesVersionNumber = 1 * 8;
|
||||
long pos_localTablesVersionNumber = 22 * 8;
|
||||
|
||||
long typicalYear2 = 0; /* corrected */
|
||||
long typicalYear2 = 0; // corrected
|
||||
long nbits_typicalYear = 2 * 8;
|
||||
long pos_typicalYear = 23 * 8;
|
||||
|
||||
|
@ -482,11 +480,11 @@ static int bufr_decode_edition4(const void* message, codes_bufr_header* hdr)
|
|||
long offset_section2 = 0;
|
||||
long offset_section3 = 0;
|
||||
long nbits_numberOfSubsets = 2 * 8;
|
||||
long pos_numberOfSubsets = 0; /*depends on offset_section3*/
|
||||
long pos_numberOfSubsets = 0; //depends on offset_section3
|
||||
|
||||
unsigned long section3Flags;
|
||||
long nbits_section3Flags = 1 * 8;
|
||||
long pos_section3Flags = 0; /*depends on offset_section3*/
|
||||
long pos_section3Flags = 0; //depends on offset_section3
|
||||
|
||||
totalLength = grib_decode_unsigned_long(pMessage, &pos_totalLength, nbits_totalLength);
|
||||
if (totalLength != hdr->message_size) {
|
||||
|
@ -505,7 +503,7 @@ static int bufr_decode_edition4(const void* message, codes_bufr_header* hdr)
|
|||
hdr->localTablesVersionNumber = (long)grib_decode_unsigned_long(pMessage, &pos_localTablesVersionNumber, nbits_localTablesVersionNumber);
|
||||
|
||||
hdr->typicalYear = (long)grib_decode_unsigned_long(pMessage, &pos_typicalYear, nbits_typicalYear);
|
||||
typicalYear2 = hdr->typicalYear < 100 ? 2000 + hdr->typicalYear : hdr->typicalYear; /*ECC-556*/
|
||||
typicalYear2 = hdr->typicalYear < 100 ? 2000 + hdr->typicalYear : hdr->typicalYear; //ECC-556
|
||||
hdr->typicalMonth = (long)grib_decode_unsigned_long(pMessage, &pos_typicalMonth, nbits_typicalMonth);
|
||||
hdr->typicalDay = (long)grib_decode_unsigned_long(pMessage, &pos_typicalDay, nbits_typicalDay);
|
||||
hdr->typicalHour = (long)grib_decode_unsigned_long(pMessage, &pos_typicalHour, nbits_typicalHour);
|
||||
|
@ -514,7 +512,7 @@ static int bufr_decode_edition4(const void* message, codes_bufr_header* hdr)
|
|||
hdr->typicalDate = typicalYear2 * 10000 + hdr->typicalMonth * 100 + hdr->typicalDay;
|
||||
hdr->typicalTime = hdr->typicalHour * 10000 + hdr->typicalMinute * 100 + hdr->typicalSecond;
|
||||
|
||||
offset_section2 = BUFR_SECTION0_LEN + section1Length; /*bytes*/
|
||||
offset_section2 = BUFR_SECTION0_LEN + section1Length; //bytes
|
||||
section2Length = 0;
|
||||
hdr->localSectionPresent = (section1Flags != 0);
|
||||
if (hdr->localSectionPresent) {
|
||||
|
@ -530,7 +528,7 @@ static int bufr_decode_edition4(const void* message, codes_bufr_header* hdr)
|
|||
}
|
||||
}
|
||||
|
||||
offset_section3 = BUFR_SECTION0_LEN + section1Length + section2Length; /*bytes*/
|
||||
offset_section3 = BUFR_SECTION0_LEN + section1Length + section2Length; //bytes
|
||||
pos_numberOfSubsets = (offset_section3 + 4) * 8;
|
||||
hdr->numberOfSubsets = grib_decode_unsigned_long(pMessage, &pos_numberOfSubsets, nbits_numberOfSubsets);
|
||||
|
||||
|
@ -584,10 +582,10 @@ static int count_bufr_messages(grib_context* c, FILE* f, int* n, int strict_mode
|
|||
|
||||
while (!done) {
|
||||
mesg = wmo_read_bufr_from_file_malloc(f, 0, &size, &offset, &err);
|
||||
/*printf("Count so far=%d, mesg=%x, err=%d (%s)\n", *n, mesg, err, grib_get_error_message(err));*/
|
||||
//printf("Count so far=%d, mesg=%x, err=%d (%s)\n", *n, mesg, err, grib_get_error_message(err));
|
||||
if (!mesg) {
|
||||
if (err == GRIB_END_OF_FILE || err == GRIB_PREMATURE_END_OF_FILE) {
|
||||
done = 1; /* reached the end */
|
||||
done = 1; // reached the end
|
||||
break;
|
||||
}
|
||||
if (strict_mode)
|
||||
|
@ -669,7 +667,7 @@ int codes_bufr_extract_headers_malloc(grib_context* c, const char* filename, cod
|
|||
}
|
||||
if (!mesg) {
|
||||
if (err != GRIB_END_OF_FILE && err != GRIB_PREMATURE_END_OF_FILE) {
|
||||
/* An error occurred */
|
||||
// An error occurred
|
||||
grib_context_log(c, GRIB_LOG_ERROR, "codes_bufr_extract_headers_malloc: Unable to read BUFR message");
|
||||
if (strict_mode) {
|
||||
fclose(fp);
|
||||
|
@ -786,7 +784,7 @@ static const char* codes_bufr_header_get_centre_name(long edition, long centre_c
|
|||
}
|
||||
|
||||
#if 0
|
||||
/* TODO: Not efficient as it opens the code table every time */
|
||||
// TODO: Not efficient as it opens the code table every time
|
||||
static char* codes_bufr_header_get_centre_name(long edition, long centre_code)
|
||||
{
|
||||
char full_path[2014] = {0,};
|
||||
|
@ -849,7 +847,7 @@ int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char* v
|
|||
bool isEcmwfLocal = false;
|
||||
Assert(bh);
|
||||
Assert(key);
|
||||
*len = strlen(NOT_FOUND); /*By default*/
|
||||
*len = strlen(NOT_FOUND); // By default
|
||||
|
||||
isEcmwfLocal = (bh->ecmwfLocalSectionPresent == 1);
|
||||
Assert(!(isEcmwfLocal && bh->bufrHeaderCentre != 98));
|
||||
|
@ -913,7 +911,7 @@ int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char* v
|
|||
else if (strcmp(key, "ecmwfLocalSectionPresent") == 0)
|
||||
*len = snprintf(val, 32, "%ld", bh->ecmwfLocalSectionPresent);
|
||||
|
||||
/* Local ECMWF keys. Can be absent so must return NOT_FOUND */
|
||||
// Local ECMWF keys. Can be absent so must return NOT_FOUND
|
||||
else if (strcmp(key, "rdbType") == 0) {
|
||||
if (isEcmwfLocal)
|
||||
*len = snprintf(val, 32, "%ld", bh->rdbType);
|
||||
|
@ -1113,7 +1111,7 @@ int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char* v
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
/* Returns 1 if the BUFR key is in the header and 0 if it is in the data section */
|
||||
// Returns 1 if the BUFR key is in the header and 0 if it is in the data section
|
||||
int codes_bufr_key_is_header(const grib_handle* h, const char* key, int* err)
|
||||
{
|
||||
grib_accessor* acc = grib_find_accessor(h, key);
|
||||
|
@ -1121,5 +1119,18 @@ int codes_bufr_key_is_header(const grib_handle* h, const char* key, int* err)
|
|||
*err = GRIB_NOT_FOUND;
|
||||
return 0;
|
||||
}
|
||||
*err = GRIB_SUCCESS;
|
||||
return ((acc->flags & GRIB_ACCESSOR_FLAG_BUFR_DATA) == 0);
|
||||
}
|
||||
|
||||
// Returns 1 if the BUFR key is a coordinate descriptor
|
||||
int codes_bufr_key_is_coordinate(const grib_handle* h, const char* key, int* err)
|
||||
{
|
||||
grib_accessor* acc = grib_find_accessor(h, key);
|
||||
if (!acc) {
|
||||
*err = GRIB_NOT_FOUND;
|
||||
return 0;
|
||||
}
|
||||
*err = GRIB_SUCCESS;
|
||||
return ((acc->flags & GRIB_ACCESSOR_FLAG_BUFR_COORD) != 0);
|
||||
}
|
||||
|
|
|
@ -1360,6 +1360,10 @@ int codes_is_defined(const codes_handle* h, const char* key);
|
|||
The error code is the final argument */
|
||||
int codes_bufr_key_is_header(const codes_handle* h, const char* key, int* err);
|
||||
|
||||
/* Returns 1 if the BUFR key is a coordinate descriptor and 0 otherwise.
|
||||
The error code is the final argument */
|
||||
int codes_bufr_key_is_coordinate(const codes_handle* h, const char* key, int* err);
|
||||
|
||||
int codes_set_missing(codes_handle* h, const char* key);
|
||||
/* The truncation is the Gaussian number (or order) */
|
||||
int codes_get_gaussian_latitudes(long truncation, double* latitudes);
|
||||
|
|
|
@ -1479,6 +1479,7 @@ int codes_bufr_copy_data(grib_handle* hin, grib_handle* hout);
|
|||
int codes_bufr_extract_headers_malloc(grib_context* c, const char* filename, codes_bufr_header** result, int* num_messages, int strict_mode);
|
||||
int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char* val, size_t* len);
|
||||
int codes_bufr_key_is_header(const grib_handle* h, const char* key, int* err);
|
||||
int codes_bufr_key_is_coordinate(const grib_handle* h, const char* key, int* err);
|
||||
|
||||
/* string_util.cc*/
|
||||
int strcmp_nocase(const char* s1, const char* s2);
|
||||
|
|
|
@ -1961,7 +1961,8 @@ static int adding_extra_key_attributes(grib_handle* h)
|
|||
}
|
||||
|
||||
static grib_accessor* create_accessor_from_descriptor(const grib_accessor* a, grib_accessor* attribute, grib_section* section,
|
||||
long ide, long subset, int add_dump_flag, int count, int add_extra_attributes)
|
||||
long ide, long subset, int add_dump_flag, int add_coord_flag,
|
||||
int count, int add_extra_attributes)
|
||||
{
|
||||
grib_accessor_bufr_data_array* self = (grib_accessor_bufr_data_array*)a;
|
||||
char code[10] = {0,};
|
||||
|
@ -1989,6 +1990,9 @@ static grib_accessor* create_accessor_from_descriptor(const grib_accessor* a, gr
|
|||
creator.flags = GRIB_ACCESSOR_FLAG_DUMP;
|
||||
operatorCreator.flags |= GRIB_ACCESSOR_FLAG_DUMP;
|
||||
}
|
||||
if (add_coord_flag) {
|
||||
creator.flags |= GRIB_ACCESSOR_FLAG_BUFR_COORD; // ECC-1611
|
||||
}
|
||||
|
||||
idx = self->compressedData ? self->elementsDescriptorsIndex->v[0]->v[ide] : self->elementsDescriptorsIndex->v[subset]->v[ide];
|
||||
|
||||
|
@ -1996,6 +2000,7 @@ static grib_accessor* create_accessor_from_descriptor(const grib_accessor* a, gr
|
|||
case 0:
|
||||
case 1:
|
||||
creator.name = grib_context_strdup(a->context, self->expanded->v[idx]->shortName);
|
||||
|
||||
/* ECC-325: store alloc'd string (due to strdup) for clean up later */
|
||||
grib_sarray_push(a->context, self->tempStrings, creator.name);
|
||||
elementAccessor = grib_accessor_factory(section, &creator, 0, NULL);
|
||||
|
@ -2466,7 +2471,7 @@ static int create_keys(const grib_accessor* a, long onlySubset, long startSubset
|
|||
grib_accessor* elementFromBitmap = NULL;
|
||||
grib_handle* hand = grib_handle_of_accessor(a);
|
||||
/*int reuseBitmap=0;*/
|
||||
int add_dump_flag = 1, count = 0;
|
||||
int add_dump_flag = 1, add_coord_flag = 0, count = 0;
|
||||
/*int forceGroupClosure=0;*/
|
||||
|
||||
creatorGroup.op = (char*)"bufr_group";
|
||||
|
@ -2533,11 +2538,13 @@ static int create_keys(const grib_accessor* a, long onlySubset, long startSubset
|
|||
continue; /* Descriptor does not have an associated key e.g. inside op 203YYY */
|
||||
}
|
||||
elementFromBitmap = NULL;
|
||||
add_coord_flag = 0;
|
||||
if (descriptor->F == 0 && IS_COORDINATE_DESCRIPTOR(descriptor->X) &&
|
||||
self->unpackMode == CODES_BUFR_UNPACK_STRUCTURE) {
|
||||
const int sidx = descriptor->Y + significanceQualifierIndexArray[descriptor->X] * NUMBER_OF_QUALIFIERS_PER_CATEGORY;
|
||||
DebugAssert(sidx > 0);
|
||||
groupNumber++;
|
||||
add_coord_flag = 1;
|
||||
|
||||
if (significanceQualifierGroup[sidx]) {
|
||||
groupSection = significanceQualifierGroup[sidx]->parent;
|
||||
|
@ -2562,6 +2569,7 @@ static int create_keys(const grib_accessor* a, long onlySubset, long startSubset
|
|||
gaGroup = grib_accessor_factory(groupSection, &creatorGroup, 0, NULL);
|
||||
gaGroup->sub_section = grib_section_create(hand, gaGroup);
|
||||
gaGroup->bufr_group_number = groupNumber;
|
||||
|
||||
accessor_constant_set_type(gaGroup, GRIB_TYPE_LONG);
|
||||
accessor_constant_set_dval(gaGroup, groupNumber);
|
||||
grib_push_accessor(gaGroup, groupSection->block);
|
||||
|
@ -2675,7 +2683,8 @@ static int create_keys(const grib_accessor* a, long onlySubset, long startSubset
|
|||
grib_accessors_list_push(self->dataAccessors, asn, rank);
|
||||
}
|
||||
count++;
|
||||
elementAccessor = create_accessor_from_descriptor(a, associatedFieldAccessor, section, ide, iss, add_dump_flag, count, add_extra_attributes);
|
||||
elementAccessor = create_accessor_from_descriptor(a, associatedFieldAccessor, section, ide, iss,
|
||||
add_dump_flag, add_coord_flag, count, add_extra_attributes);
|
||||
if (!elementAccessor) {
|
||||
err = GRIB_DECODING_ERROR;
|
||||
return err;
|
||||
|
|
|
@ -57,8 +57,6 @@ static void init(grib_accessor*, const long, grib_arguments*);
|
|||
//static void init_class(grib_accessor_class*);
|
||||
static int unpack_double_element(grib_accessor*, size_t i, double* val);
|
||||
static int unpack_double_element_set(grib_accessor*, const size_t* index_array, size_t len, double* val_array);
|
||||
static bool is_big_endian();
|
||||
static void modify_aec_flags(long& flags);
|
||||
|
||||
typedef struct grib_accessor_data_ccsds_packing
|
||||
{
|
||||
|
@ -176,7 +174,24 @@ static int value_count(grib_accessor* a, long* count)
|
|||
#error Version of libaec appears to be too old. Please upgrade.
|
||||
#endif
|
||||
|
||||
const char* aec_get_error_message(int code)
|
||||
static bool is_big_endian()
|
||||
{
|
||||
unsigned char is_big_endian = 0;
|
||||
unsigned short endianess_test = 1;
|
||||
return reinterpret_cast<const char*>(&endianess_test)[0] == is_big_endian;
|
||||
}
|
||||
|
||||
static void modify_aec_flags(long* flags)
|
||||
{
|
||||
// ECC-1602: Performance improvement: enabled the use of native data types
|
||||
*flags &= ~AEC_DATA_3BYTE; // disable support for 3-bytes per value
|
||||
if (is_big_endian())
|
||||
*flags |= AEC_DATA_MSB; // enable big-endian
|
||||
else
|
||||
*flags &= ~AEC_DATA_MSB; // enable little-endian
|
||||
}
|
||||
|
||||
static const char* aec_get_error_message(int code)
|
||||
{
|
||||
if (code == AEC_MEM_ERROR) return "AEC_MEM_ERROR";
|
||||
if (code == AEC_DATA_ERROR) return "AEC_DATA_ERROR";
|
||||
|
@ -186,7 +201,7 @@ const char* aec_get_error_message(int code)
|
|||
return "Unknown error code";
|
||||
}
|
||||
|
||||
void print_aec_stream_info(struct aec_stream* strm, const char* func)
|
||||
static void print_aec_stream_info(struct aec_stream* strm, const char* func)
|
||||
{
|
||||
fprintf(stderr, "ECCODES DEBUG CCSDS %s aec_stream.flags=%u\n", func, strm->flags);
|
||||
fprintf(stderr, "ECCODES DEBUG CCSDS %s aec_stream.bits_per_sample=%u\n", func, strm->bits_per_sample);
|
||||
|
@ -243,7 +258,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
|||
if ((err = grib_get_long_internal(hand, self->ccsds_rsi, &ccsds_rsi)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
modify_aec_flags(ccsds_flags);
|
||||
modify_aec_flags(&ccsds_flags);
|
||||
|
||||
// Special case
|
||||
if (*len == 0) {
|
||||
|
@ -482,23 +497,6 @@ cleanup:
|
|||
return err;
|
||||
}
|
||||
|
||||
static bool is_big_endian()
|
||||
{
|
||||
unsigned char is_big_endian = 0;
|
||||
unsigned short endianess_test = 1;
|
||||
return reinterpret_cast<const char*>(&endianess_test)[0] == is_big_endian;
|
||||
}
|
||||
|
||||
static void modify_aec_flags(long& flags)
|
||||
{
|
||||
// ECC-1602: Performance improvement: enabled the use of native data types
|
||||
flags &= ~AEC_DATA_3BYTE; // disable support for 3-bytes per value
|
||||
if (is_big_endian())
|
||||
flags |= AEC_DATA_MSB; // enable big-endian
|
||||
else
|
||||
flags &= ~AEC_DATA_MSB; // enable little-endian
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int unpack(grib_accessor* a, T* val, size_t* len)
|
||||
{
|
||||
|
@ -553,7 +551,7 @@ static int unpack(grib_accessor* a, T* val, size_t* len)
|
|||
if ((err = grib_get_long_internal(hand, self->ccsds_rsi, &ccsds_rsi)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
modify_aec_flags(ccsds_flags);
|
||||
modify_aec_flags(&ccsds_flags);
|
||||
|
||||
// TODO(masn): This should be called upstream
|
||||
if (*len < n_vals)
|
||||
|
|
|
@ -562,23 +562,24 @@ struct grib_accessor
|
|||
grib_accessor* parent_as_attribute;
|
||||
};
|
||||
|
||||
#define GRIB_ACCESSOR_FLAG_READ_ONLY (1 << 1)
|
||||
#define GRIB_ACCESSOR_FLAG_DUMP (1 << 2)
|
||||
#define GRIB_ACCESSOR_FLAG_READ_ONLY (1 << 1)
|
||||
#define GRIB_ACCESSOR_FLAG_DUMP (1 << 2)
|
||||
#define GRIB_ACCESSOR_FLAG_EDITION_SPECIFIC (1 << 3)
|
||||
#define GRIB_ACCESSOR_FLAG_CAN_BE_MISSING (1 << 4)
|
||||
#define GRIB_ACCESSOR_FLAG_HIDDEN (1 << 5)
|
||||
#define GRIB_ACCESSOR_FLAG_CONSTRAINT (1 << 6)
|
||||
#define GRIB_ACCESSOR_FLAG_BUFR_DATA (1 << 7)
|
||||
#define GRIB_ACCESSOR_FLAG_NO_COPY (1 << 8)
|
||||
#define GRIB_ACCESSOR_FLAG_COPY_OK (1 << 9)
|
||||
#define GRIB_ACCESSOR_FLAG_FUNCTION (1 << 10)
|
||||
#define GRIB_ACCESSOR_FLAG_DATA (1 << 11)
|
||||
#define GRIB_ACCESSOR_FLAG_NO_FAIL (1 << 12)
|
||||
#define GRIB_ACCESSOR_FLAG_TRANSIENT (1 << 13)
|
||||
#define GRIB_ACCESSOR_FLAG_STRING_TYPE (1 << 14)
|
||||
#define GRIB_ACCESSOR_FLAG_LONG_TYPE (1 << 15)
|
||||
#define GRIB_ACCESSOR_FLAG_DOUBLE_TYPE (1 << 16)
|
||||
#define GRIB_ACCESSOR_FLAG_LOWERCASE (1 << 17)
|
||||
#define GRIB_ACCESSOR_FLAG_CAN_BE_MISSING (1 << 4)
|
||||
#define GRIB_ACCESSOR_FLAG_HIDDEN (1 << 5)
|
||||
#define GRIB_ACCESSOR_FLAG_CONSTRAINT (1 << 6)
|
||||
#define GRIB_ACCESSOR_FLAG_BUFR_DATA (1 << 7)
|
||||
#define GRIB_ACCESSOR_FLAG_NO_COPY (1 << 8)
|
||||
#define GRIB_ACCESSOR_FLAG_COPY_OK (1 << 9)
|
||||
#define GRIB_ACCESSOR_FLAG_FUNCTION (1 << 10)
|
||||
#define GRIB_ACCESSOR_FLAG_DATA (1 << 11)
|
||||
#define GRIB_ACCESSOR_FLAG_NO_FAIL (1 << 12)
|
||||
#define GRIB_ACCESSOR_FLAG_TRANSIENT (1 << 13)
|
||||
#define GRIB_ACCESSOR_FLAG_STRING_TYPE (1 << 14)
|
||||
#define GRIB_ACCESSOR_FLAG_LONG_TYPE (1 << 15)
|
||||
#define GRIB_ACCESSOR_FLAG_DOUBLE_TYPE (1 << 16)
|
||||
#define GRIB_ACCESSOR_FLAG_LOWERCASE (1 << 17)
|
||||
#define GRIB_ACCESSOR_FLAG_BUFR_COORD (1 << 18)
|
||||
|
||||
/**
|
||||
* a section accessor
|
||||
|
|
|
@ -41,6 +41,7 @@ list(APPEND test_c_bins
|
|||
bufr_extract_headers
|
||||
extract_offsets
|
||||
bufr_check_descriptors
|
||||
bufr_coordinate_descriptors
|
||||
codes_new_from_samples
|
||||
codes_set_samples_path
|
||||
grib_sh_ieee64
|
||||
|
@ -147,6 +148,7 @@ if( HAVE_BUILD_TOOLS )
|
|||
bufr_templates
|
||||
bufr_dump_data
|
||||
bufr_dump_descriptors
|
||||
bufr_coordinate_descriptors
|
||||
bufr_dump_subset
|
||||
bufr_dump_decode_filter
|
||||
bufr_dump_encode_filter
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* (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 "eccodes.h"
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
// Get the X part of a BUFR descriptor (FXY) and determine if it
|
||||
// is a coordinate.
|
||||
// See https://confluence.ecmwf.int/display/UDOC/What+are+coordinate+descriptors+-+ecCodes+BUFR+FAQ
|
||||
static int is_coord_using_Xcode(const char* X)
|
||||
{
|
||||
if (strcmp(X, "01") == 0) return 1;
|
||||
if (strcmp(X, "02") == 0) return 1;
|
||||
if (strcmp(X, "04") == 0) return 1;
|
||||
if (strcmp(X, "05") == 0) return 1;
|
||||
if (strcmp(X, "06") == 0) return 1;
|
||||
if (strcmp(X, "07") == 0) return 1;
|
||||
if (strcmp(X, "08") == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int err = 0;
|
||||
codes_handle* h = NULL;
|
||||
char* filename = NULL;
|
||||
FILE* fin = NULL;
|
||||
int is_coord = 0;
|
||||
|
||||
assert (argc == 2);
|
||||
filename = argv[1];
|
||||
|
||||
fin = fopen(filename, "rb");
|
||||
assert(fin);
|
||||
while ((h = codes_handle_new_from_file(NULL, fin, PRODUCT_BUFR, &err)) != NULL || err != CODES_SUCCESS) {
|
||||
codes_bufr_keys_iterator* kiter = NULL;
|
||||
CODES_CHECK(codes_set_long(h, "unpack", 1), 0);
|
||||
kiter = codes_bufr_keys_iterator_new(h, 0);
|
||||
assert(kiter);
|
||||
while (codes_bufr_keys_iterator_next(kiter)) {
|
||||
char* name = codes_bufr_keys_iterator_get_name(kiter);
|
||||
if (strcmp(name, "subsetNumber") == 0) continue;
|
||||
if (!codes_bufr_key_is_header(h, name, &err) && !err) {
|
||||
char name1[256] = {0,};
|
||||
char scode[256] = {0,};
|
||||
char X[3] = {0,}; // the 'X' part of FXY
|
||||
size_t slen = 256;
|
||||
snprintf(name1, 256, "%s->code", name);
|
||||
int error = codes_get_string(h, name1, scode, &slen);
|
||||
if (!error) {
|
||||
assert(strlen(scode) == 6);
|
||||
X[0] = scode[1];
|
||||
X[1] = scode[2];
|
||||
X[2] = 0;
|
||||
int is_X_coord = is_coord_using_Xcode(X);
|
||||
is_coord = codes_bufr_key_is_coordinate(h, name, &error);
|
||||
assert(!error);
|
||||
if (is_coord != is_X_coord) {
|
||||
fprintf(stderr, "ERROR: %s X=%s is_coord=%d is_X_coord=%d\n", name, X, is_coord, is_X_coord);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// header keys cannot be coordinate descriptors
|
||||
is_coord = codes_bufr_key_is_coordinate(h, name, &err);
|
||||
assert(!is_coord);
|
||||
}
|
||||
}
|
||||
|
||||
is_coord = codes_bufr_key_is_coordinate(h, "nosuchkey", &err);
|
||||
assert(err == CODES_NOT_FOUND);
|
||||
|
||||
codes_bufr_keys_iterator_delete(kiter);
|
||||
codes_handle_delete(h);
|
||||
}
|
||||
fclose(fin);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#!/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
|
||||
|
||||
label="bufr_coordinate_descriptors_test"
|
||||
temp=temp.$label.txt
|
||||
|
||||
bufr_files=`cat ${data_dir}/bufr/bufr_data_files.txt`
|
||||
for f in ${bufr_files}; do
|
||||
fpath=${data_dir}/bufr/$f
|
||||
${test_dir}/bufr_coordinate_descriptors $fpath
|
||||
done
|
||||
rm -f $temp
|
Loading…
Reference in New Issue