Merge branch 'develop' into feature/Template4refactoring

This commit is contained in:
Shahram Najm 2021-02-18 16:25:44 +00:00
commit bc33269b52
92 changed files with 5882 additions and 5731 deletions

View File

@ -14041,7 +14041,6 @@ dist_definitionsgrib2_DATA = \
grib2/template.7.6.def\
grib2/template.7.61.def\
grib2/template.7.second_order.def\
grib2/template.second_order.def\
grib2/tiggeLocalVersion.table\
grib2/tigge_name.def\
grib2/tigge_parameter.def\

View File

@ -22,11 +22,11 @@
# parameterNumber
# # The following are optional keys
# typeOfFirstFixedSurface
# typeOfSecondFixedSurface
# scaledValueOfFirstFixedSurface
# scaleFactorOfFirstFixedSurface
# scaledValueOfSecondFixedSurface
# scaledValueOfFirstFixedSurface
# typeOfSecondFixedSurface
# scaleFactorOfSecondFixedSurface
# scaledValueOfSecondFixedSurface
# typeOfStatisticalProcessing
#
# It outputs the def files:
@ -57,6 +57,7 @@ write_or_append(\*OUT_CFVARNAME, "$CFVARNAME_FILENAME");
my $first = 1;
while (<>) {
chomp;
s/\r//g; # Remove DOS carriage returns
if ($first == 1) {
check_first_row_column_names($_);
$first = 0;
@ -124,13 +125,12 @@ sub check_first_row_column_names {
die "Error: 1st row column titles wrong: Column 7 should be 'parameterNumber'\n" if ($keys[6] ne "parameterNumber");
die "Error: 1st row column titles wrong: Column 8 should be 'typeOfFirstFixedSurface'\n" if ($keys[7] ne "typeOfFirstFixedSurface");
die "Error: 1st row column titles wrong: Column 9 should be 'typeOfSecondFixedSurface'\n" if ($keys[8] ne "typeOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 9 should be 'scaleFactorOfFirstFixedSurface'\n" if ($keys[8] ne "scaleFactorOfFirstFixedSurface");
die "Error: 1st row column titles wrong: Column 10 should be 'scaledValueOfFirstFixedSurface'\n" if ($keys[9] ne "scaledValueOfFirstFixedSurface");
die "Error: 1st row column titles wrong: Column 11 should be 'scaleFactorOfFirstFixedSurface'\n" if ($keys[10] ne "scaleFactorOfFirstFixedSurface");
die "Error: 1st row column titles wrong: Column 12 should be 'scaledValueOfSecondFixedSurface'\n" if ($keys[11] ne "scaledValueOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 13 should be 'scaleFactorOfSecondFixedSurface'\n" if ($keys[12] ne "scaleFactorOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 11 should be 'typeOfSecondFixedSurface'\n" if ($keys[10] ne "typeOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 12 should be 'scaleFactorOfSecondFixedSurface'\n" if ($keys[11] ne "scaleFactorOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 13 should be 'scaledValueOfSecondFixedSurface'\n" if ($keys[12] ne "scaledValueOfSecondFixedSurface");
die "Error: 1st row column titles wrong: Column 14 should be 'typeOfStatisticalProcessing'\n" if ($keys[13] ne "typeOfStatisticalProcessing");
}

View File

@ -1,37 +1,4 @@
# ECMWF concept type of level
'surface' = {indicatorOfTypeOfLevel=1;}
'cloudBase' = {indicatorOfTypeOfLevel=2;}
'cloudTop' = {indicatorOfTypeOfLevel=3;}
'isothermZero' = {indicatorOfTypeOfLevel=4;}
'adiabaticCondensation' = {indicatorOfTypeOfLevel=5;}
'maxWind' = {indicatorOfTypeOfLevel=6;}
'tropopause' = {indicatorOfTypeOfLevel=7;}
'nominalTop' = {indicatorOfTypeOfLevel=8;}
'seaBottom' = {indicatorOfTypeOfLevel=9;}
'isobaricInhPa' = {indicatorOfTypeOfLevel=100;}
'isobaricInPa' = {indicatorOfTypeOfLevel=210;}
'isobaricLayer' = {indicatorOfTypeOfLevel=101;}
'meanSea' = {indicatorOfTypeOfLevel=102;}
'isobaricLayerHighPrecision' = {indicatorOfTypeOfLevel=121;}
'isobaricLayerMixedPrecision' = {indicatorOfTypeOfLevel=141;}
'heightAboveSea' = {indicatorOfTypeOfLevel=103;}
'heightAboveSeaLayer' = {indicatorOfTypeOfLevel=104;}
'heightAboveGroundHighPrecision' = {indicatorOfTypeOfLevel=125;}
'heightAboveGround' = {indicatorOfTypeOfLevel=105;}
'heightAboveGroundLayer' = {indicatorOfTypeOfLevel=106;}
'sigma' = {indicatorOfTypeOfLevel=107;}
'sigmaLayer' = {indicatorOfTypeOfLevel=108;}
'sigmaLayerHighPrecision' = {indicatorOfTypeOfLevel=128;}
'hybrid' = {indicatorOfTypeOfLevel=109;}
'hybridLayer' = {indicatorOfTypeOfLevel=110;}
'depthBelowLand' = {indicatorOfTypeOfLevel=111;}
'depthBelowLandLayer' = {indicatorOfTypeOfLevel=112;}
'theta' = {indicatorOfTypeOfLevel=113;}
'thetaLayer' = {indicatorOfTypeOfLevel=114;}
'pressureFromGround' = {indicatorOfTypeOfLevel=115;}
'pressureFromGroundLayer' = {indicatorOfTypeOfLevel=116;}
'potentialVorticity' = {indicatorOfTypeOfLevel=117;}
'depthBelowSea' = {indicatorOfTypeOfLevel=160;}
'entireAtmosphere' = {indicatorOfTypeOfLevel=200;level=0;}
'entireOcean' = {indicatorOfTypeOfLevel=201;level=0;}
'oceanWave' = {indicatorOfTypeOfLevel=211;}

View File

@ -0,0 +1,33 @@
# Concept typeOfLevel for kwbc
'atmosphereSingleLayer' = {typeOfFirstFixedSurface=200;}
'oceanSingleLayer' = {typeOfFirstFixedSurface=201;}
'highestTroposphericFreezing' = {typeOfFirstFixedSurface=204;}
'gridScaleCloudBottom' = {typeOfFirstFixedSurface=206;}
'gridScaleCloudTop' = {typeOfFirstFixedSurface=207;}
'boundaryLayerCloudBottom' = {typeOfFirstFixedSurface=209;}
'boundaryLayerCloudTop' = {typeOfFirstFixedSurface=210;}
'boundaryLayerCloudLayer' = {typeOfFirstFixedSurface=211;}
'lowCloudBottom' = {typeOfFirstFixedSurface=212;}
'lowCloudTop' = {typeOfFirstFixedSurface=213;}
'lowCloudLayer' = {typeOfFirstFixedSurface=214;}
'cloudCeiling' = {typeOfFirstFixedSurface=215;}
'planetaryBoundaryLayer' = {typeOfFirstFixedSurface=220;}
'layerBetween2Hybrids' = {typeOfFirstFixedSurface=221;}
'middleCloudBottom' = {typeOfFirstFixedSurface=222;}
'middleCloudTop' = {typeOfFirstFixedSurface=223;}
'middleCloudLayer' = {typeOfFirstFixedSurface=224;}
'highCloudBottom' = {typeOfFirstFixedSurface=232;}
'highCloudTop' = {typeOfFirstFixedSurface=233;}
'highCloudLayer' = {typeOfFirstFixedSurface=234;}
'oceanIsotherm' = {typeOfFirstFixedSurface=235;}
'oceanMixedLayer' = {typeOfFirstFixedSurface=240;}
'orderedSequenceData' = {typeOfFirstFixedSurface=241;}
'convectiveCloudBottom' = {typeOfFirstFixedSurface=242;}
'convectiveCloudTop' = {typeOfFirstFixedSurface=243;}
'convectiveCloudLayer' = {typeOfFirstFixedSurface=244;}
'lowestLevelWetBulb0' = {typeOfFirstFixedSurface=245;}
'equilibrium' = {typeOfFirstFixedSurface=247;}
'shallowConvectiveCloudBottom' = {typeOfFirstFixedSurface=248;}
'shallowConvectiveCloudTop' = {typeOfFirstFixedSurface=249;}
'deepConvectiveCloudBottom' = {typeOfFirstFixedSurface=251;}
'deepConvectiveCloudTop' = {typeOfFirstFixedSurface=252;}

View File

@ -71,19 +71,42 @@
# 192-254 Reserved for local use
# See ECC-469
200 200 Entire atmosphere (considered as a single layer)
201 201 Entire ocean (considered as a single layer)
204 204 Highest tropospheric freezing level
206 206 Grid scale cloud bottom level
207 207 Grid scale cloud top level
209 209 Boundary layer cloud bottom level
210 210 Boundary layer cloud top level
211 211 Boundary layer cloud layer
212 212 Low cloud bottom level
213 213 Low cloud top level
214 214 Low cloud layer
215 215 Cloud ceiling
220 220 Planetary boundary layer
221 221 Layer between two hybrid levels
222 222 Middle cloud bottom level
223 223 Middle cloud top level
224 224 Middle cloud layer
232 232 High cloud bottom level
233 233 High cloud top level
234 234 High cloud layer
235 235 Ocean isotherm level (1/10 deg C)
236 236 Layer between two depths below ocean surface
237 237 Bottom of ocean mixed layer
238 238 Bottom of ocean isothermal layer
239 239 Layer ocean surface and 26C ocean isothermal level
240 240 Ocean mixed layer
241 241 Ordered sequence of data
242 242 Convective cloud bottom level
243 243 Convective cloud top level
244 244 Convective cloud layer
245 245 Lowest level of the wet bulb zero
246 246 Maximum equivalent potential temperature level
247 247 Equilibrium level
248 248 Shallow convective cloud bottom level
249 249 Shallow convective cloud top level
251 251 Deep convective cloud bottom level
252 252 Deep convective cloud top level
253 253 Lowest bottom level of supercooled liquid water layer
254 254 Highest top level of supercooled liquid water layer
255 255 Missing

View File

@ -1,9 +1,6 @@
# (C) Copyright 2005- ECMWF.
# TEMPLATE 7.4, Grid point data - simple packing
# Octets 6-nn : Binary data values - binary string, with each
# (scaled)
# ???? data_values__binary_string_with_each
# TEMPLATE 7.4, Grid point data - IEEE floating point data
meta codedValues data_raw_packing(
section7Length,

View File

@ -1 +0,0 @@
#TODO

View File

@ -12,7 +12,6 @@
* C Implementation: grib_iterator
*
* Description: how to use an iterator on lat/lon/values for GRIB messages
*
*/
#include <stdio.h>
@ -33,6 +32,7 @@ int main(int argc, char** argv)
double lat, lon, value;
double missingValue = 1e+20; /* A value out of range */
int n = 0;
long bitmapPresent = 0;
char* filename = NULL;
/* Message handle. Required in all the ecCodes calls acting on a message.*/
@ -55,9 +55,14 @@ int main(int argc, char** argv)
/* Check of errors after reading a message. */
if (err != CODES_SUCCESS) CODES_CHECK(err, 0);
/* Check if a bitmap applies */
CODES_CHECK(codes_get_long(h, "bitmapPresent", &bitmapPresent), 0);
if (bitmapPresent) {
/* Set the double representing the missing value in the field. */
/* Choose a missingValue that does not correspond to any real value in the data array */
CODES_CHECK(codes_set_double(h, "missingValue", missingValue), 0);
}
/* A new iterator on lat/lon/values is created from the message handle h. */
iter = codes_grib_iterator_new(h, 0, &err);
@ -69,7 +74,7 @@ int main(int argc, char** argv)
/* You can now print lat and lon, */
printf("- %d - lat=%f lon=%f value=", n, lat, lon);
/* decide what to print if a missing value is found. */
if (value == missingValue) printf("missing\n");
if (bitmapPresent && value == missingValue) printf("missing\n");
/* and print the value if is not missing. */
else
printf("%f\n", value);

View File

@ -8,8 +8,15 @@
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
. ./include.sh
temp=temp.c_grib_iterator.txt
# These two do not have any missing data
${examples_dir}/c_grib_iterator ${data_dir}/reduced_gaussian_model_level.grib1 > /dev/null
${examples_dir}/c_grib_iterator ${data_dir}/regular_gaussian_model_level.grib1 > /dev/null
# Has missing data
${examples_dir}/c_grib_iterator ${data_dir}/reduced_latlon_surface.grib2 > $temp
count_miss=`grep -c missing $temp`
[ $count_miss = 98701 ]
rm -f $temp

View File

@ -37,7 +37,6 @@ character(len=32) :: units, confUnits
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! ----------------------------------------------------------------
! We will read the value and all the attributes available for
! the 2m temperature.

View File

@ -36,7 +36,6 @@ real(kind=8), dimension(:), allocatable :: values
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! Get the expanded data values
call codes_get(ibufr, 'numericValues', values)

View File

@ -39,7 +39,6 @@ character(len=9) :: typicalDate
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! Get as character
call codes_get(ibufr, 'typicalDate', typicalDate)
write (*, *) ' typicalDate:', typicalDate

View File

@ -38,7 +38,6 @@ integer :: kiter
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! Create BUFR keys iterator
call codes_bufr_keys_iterator_new(ibufr, kiter, iret)

View File

@ -15,7 +15,6 @@
! below might not work directly for other types of messages than the one used in the
! example. It is advised to use bufr_dump first to understand the structure of these messages.
program bufr_read_scatterometer
use eccodes
implicit none
@ -40,7 +39,6 @@ real(kind=8), dimension(:), allocatable :: year
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! The BUFR file contains a single message with 2016 subsets in a compressed form.
! It means each subset has exactly the same structure: they store one location with
! several beams and one backscatter value in each beam.
@ -55,10 +53,8 @@ real(kind=8), dimension(:), allocatable :: year
! Get latitude (for all the subsets)
call codes_get(ibufr, 'latitude', latVal);
! Get longitude (for all the subsets)
call codes_get(ibufr, 'longitude', lonVal);
allocate (year(numObs))
call codes_get(ibufr, 'year', year);
do ii = 1, size(year)
@ -68,7 +64,6 @@ real(kind=8), dimension(:), allocatable :: year
! Get backScatter for beam two. We use an access by condition for this key.
! (for all the subsets)
call codes_get(ibufr, '/beamIdentifier=2/backscatter', bscatterVal);
! Check that all arrays are same size
if (size(latVal) /= numObs .or. size(lonVal) /= numObs .or. size(bscatterVal) /= numObs) then
print *, 'inconsistent array dimension'

View File

@ -54,7 +54,6 @@ program bufr_read_temp
! we need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, "unpack", 1);
! In our BUFR message verticalSoundingSignificance is always followed by
! geopotential, airTemperature, dewpointTemperature,
! windDirection, windSpeed and pressure.

View File

@ -52,7 +52,6 @@ program bufr_read_tropical_cyclone
! We need to instruct ecCodes to unpack the data values
call codes_set(ibufr, "unpack", 1);
call codes_get(ibufr, 'year', year);
call codes_get(ibufr, 'month', month);
call codes_get(ibufr, 'day', day);
@ -234,8 +233,9 @@ program bufr_read_tropical_cyclone
write (*, *) 'step latitude longitude pressure latitude longitude wind'
do j = 1, size(period)
if (latitude(i, j) /= CODES_MISSING_DOUBLE .OR. latitudeWind(i, j) /= CODES_MISSING_DOUBLE) then
write(*,'( I4,2X,F8.2,4X,F8.2,3X,F9.1,2X,F8.2,4X,F8.2,2X,F8.2)') period(j),latitude(i,j),longitude(i,j),pressure(i,j),&
&latitudeWind(i,j),longitudeWind(i,j),wind(i,j)
write (*, '( I4,2X,F8.2,4X,F8.2,3X,F9.1,2X,F8.2,4X,F8.2,2X,F8.2)') &
period(j), latitude(i, j), longitude(i, j), pressure(i, j), &
latitudeWind(i, j), longitudeWind(i, j), wind(i, j)
end if
end do

View File

@ -38,7 +38,6 @@ character(100) :: key
! We need to instruct ecCodes to expand all the descriptors
! i.e. unpack the data values
call codes_set(ibufr, 'unpack', 1);
! Find out the number of subsets
call codes_get(ibufr, 'numberOfSubsets', numberOfSubsets)
write (*, *) ' numberOfSubsets:', numberOfSubsets

View File

@ -23,7 +23,6 @@ program copy
character(len=1), dimension(:), allocatable :: message
character(len=32) :: product_kind
call codes_open_file(infile, '../../data/constant_field.grib1', 'r')
call codes_open_file(outfile, 'out.copy.grib1', 'w')

View File

@ -81,7 +81,6 @@ program get
write (*, *) 'longitudeOfLastGridPointInDegrees=', &
longitudeOfLastPointInDegrees
! get the size of the values array
call codes_get_size(igrib(i), 'values', numberOfValues)
write (*, *) 'numberOfValues=', numberOfValues

View File

@ -57,7 +57,6 @@ program keys_iterator
call codes_grib_new_from_file(ifile, igrib, iret)
end do
call codes_close_file(ifile)
end program keys_iterator

View File

@ -35,7 +35,6 @@ use eccodes
call codes_check(iret, 'new_from_file', '')
end if
call codes_close_file(ifile)
end program

View File

@ -11,41 +11,43 @@
/*
* C Implementation: grib_iterator
*
* Description: how to use an iterator on lat/lon/values.
* Description: how to use an iterator on lat/lon/values for GRIB messages
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "grib_api.h"
static void usage(const char* prog) {
static void usage(const char* prog)
{
printf("Usage: %s grib_file\n", prog);
exit(1);
}
int main(int argc, char** argv) {
int main(int argc, char** argv)
{
FILE* in = NULL;
int err = 0;
double lat, lon, value;
double missingValue = 1e+20; /* A value out of range */
int n = 0;
long bitmapPresent = 0;
char* filename = NULL;
/* Message handle. Required in all the grib_api calls acting on a message.*/
/* Message handle. Required in all the ecCodes calls acting on a message.*/
grib_handle* h = NULL;
/* Iterator on lat/lon/values.*/
grib_iterator* iter = NULL;
if (argc != 2) usage(argv[0]);
filename=strdup(argv[1]);
filename = argv[1];
in = fopen(filename, "rb");
if (!in) {
printf("ERROR: unable to open file %s\n",filename);
fprintf(stderr, "Error: unable to open file %s\n", filename);
return 1;
}
@ -54,9 +56,14 @@ int main(int argc, char** argv) {
/* Check of errors after reading a message. */
if (err != GRIB_SUCCESS) GRIB_CHECK(err, 0);
/* Check if a bitmap applies */
GRIB_CHECK(grib_get_long(h, "bitmapPresent", &bitmapPresent), 0);
if (bitmapPresent) {
/* Set the double representing the missing value in the field. */
/* Choose a missingValue that does not correspond to any real value in the data array */
GRIB_CHECK(grib_set_double(h, "missingValue", missingValue), 0);
}
/* A new iterator on lat/lon/values is created from the message handle h. */
iter = grib_iterator_new(h, 0, &err);
@ -68,9 +75,10 @@ int main(int argc, char** argv) {
/* You can now print lat and lon, */
printf("- %d - lat=%.6e lon=%.6e value=", n, lat, lon);
/* decide what to print if a missing value is found. */
if (value == missingValue ) printf("missing\n");
if (bitmapPresent && value == missingValue) printf("missing\n");
/* and print the value if is not missing. */
else printf("%f\n",value);
else
printf("%f\n", value);
n++;
}
@ -81,7 +89,6 @@ int main(int argc, char** argv) {
grib_handle_delete(h);
}
fclose(in);
return 0;

View File

@ -19,13 +19,16 @@ missingValue = 1e+20 # A value out of range
def example(INPUT):
f = open(INPUT, 'rb')
f = open(INPUT, "rb")
while 1:
gid = codes_grib_new_from_file(f)
if gid is None:
break
bitmapPresent = codes_get(gid, "bitmapPresent")
if bitmapPresent:
# Set the value representing the missing value in the field.
# Choose a missingValue that does not correspond to any real value in the data array
codes_set(gid, "missingValue", missingValue)
@ -42,7 +45,7 @@ def example(INPUT):
sys.stdout.write("- %d - lat=%.6e lon=%.6e value=" % (i, lat, lon))
if value == missingValue:
if bitmapPresent and value == missingValue:
print("missing")
else:
print("%.6f" % value)

View File

@ -24,7 +24,6 @@ module eccodes
integer, parameter, public :: CODES_PRODUCT_GRIB = 1
integer, parameter, public :: CODES_PRODUCT_BUFR = 2
!> Create a new message in memory from an integer or character array containting the coded message.
!>
!> The message can be accessed through its ID and it will be available\n

View File

@ -6,7 +6,6 @@
! 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.
!> Get the distinct values of the key in argument contained in the index. The key must belong to the index.
!>
!>
@ -105,7 +104,6 @@
codes_get_real8_array
end interface codes_get
!> Get the size of an array key.
!>
!> To get the size of a key representing an array.

View File

@ -6,7 +6,6 @@
! 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.
!> Get the distinct values of the key in argument contained in the index. The key must belong to the index.
!>
!>

View File

@ -1096,7 +1096,6 @@ subroutine codes_bufr_new_from_file ( ifile, bufrid , status)
call bufr_new_from_file(ifile, bufrid, status)
end subroutine codes_bufr_new_from_file
!> Create a new message in memory from a character array containting the coded message.
!>
!> The message can be accessed through its msgid and it will be available\n
@ -1415,7 +1414,6 @@ subroutine codes_keys_iterator_rewind ( iterid, status )
call grib_keys_iterator_rewind(iterid, status)
end subroutine codes_keys_iterator_rewind
! BUFR keys iterator
! -----------------------
!> Create a new iterator on the keys of a BUFR message.
@ -1445,7 +1443,6 @@ subroutine codes_bufr_keys_iterator_new ( msgid, iterid, status )
end if
end subroutine codes_bufr_keys_iterator_new
!> Advance to the next BUFR keys iterator value.
!>
!> @param iterid keys iterator id created with @ref codes_bufr_keys_iterator_new
@ -1463,7 +1460,6 @@ subroutine codes_bufr_keys_iterator_next (iterid , status)
end if
end subroutine codes_bufr_keys_iterator_next
!> Get the name of a key from a BUFR keys iterator.
!>
!> If the status parameter (optional) is not given the program will exit with an error message\n
@ -1528,8 +1524,6 @@ end subroutine codes_bufr_keys_iterator_get_name
end if
end subroutine codes_bufr_keys_iterator_delete
!> Dump the content of a message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -1545,7 +1539,6 @@ subroutine codes_dump ( msgid , status)
call grib_dump(msgid, status)
end subroutine codes_dump
!> Get the API version
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -1564,7 +1557,6 @@ subroutine codes_get_api_version(api_version, status)
end if
end subroutine codes_get_api_version
!> Get the error message given an error code
!>
!> @param error error code
@ -1871,7 +1863,6 @@ subroutine codes_set_string_array ( msgid, key, value, status )
end subroutine codes_set_string_array
!> Get the integer array of values for a key from a message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2103,7 +2094,6 @@ subroutine codes_get_real8_array ( msgid, key, value, status )
end if
end subroutine codes_get_real8_array
!> Get a real(4) value of specified index from an array key.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2125,7 +2115,6 @@ subroutine codes_get_real4_element ( msgid, key, kindex,value, status )
call grib_get_real4_element(msgid, key, kindex, value, status)
end subroutine codes_get_real4_element
!> Get a real(8) value of specified index from an array key.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2147,7 +2136,6 @@ subroutine codes_get_real8_element ( msgid, key, kindex,value, status )
call grib_get_real8_element(msgid, key, kindex, value, status)
end subroutine codes_get_real8_element
!> Get the real(4) values whose indexes are stored in the array "index" from an array key.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2209,7 +2197,6 @@ subroutine codes_set_int ( msgid, key, value, status )
call grib_set_int(msgid, key, value, status)
end subroutine codes_set_int
!> Set the integer value for a key in a message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2229,7 +2216,6 @@ subroutine codes_set_long ( msgid, key, value, status )
call grib_set_long(msgid, key, value, status)
end subroutine codes_set_long
!> Set the real(4) value for a key in a message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2268,7 +2254,6 @@ subroutine codes_set_real8 ( msgid, key, value, status )
call grib_set_real8(msgid, key, value, status)
end subroutine codes_set_real8
!> Set the integers values for an array key in a message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2444,7 +2429,6 @@ subroutine codes_get_message_size_int ( msgid, nbytes, status)
call grib_get_message_size_int(msgid, nbytes, status)
end subroutine codes_get_message_size_int
!> Get the size of a coded message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2513,7 +2497,6 @@ subroutine codes_grib_multi_write ( multigribid, ifile , status)
call grib_multi_write(multigribid, ifile, status)
end subroutine codes_grib_multi_write
!> Append a single field grib message to a multi field grib message.
!> Only the sections with section number greather or equal "startsection" are copied from the input single message to the multi field output grib.
!>
@ -2605,7 +2588,6 @@ subroutine codes_grib_find_nearest_single(gribid,is_lsm, &
value, distance, kindex, status)
end subroutine codes_grib_find_nearest_single
!> Find the 4 nearest points of a latitude longitude point.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2641,7 +2623,6 @@ subroutine codes_grib_find_nearest_four_single(gribid,is_lsm, &
value, distance, kindex, status)
end subroutine codes_grib_find_nearest_four_single
!> Turn on the support for multiple fields in a single message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2765,7 +2746,6 @@ subroutine codes_skip_read_only ( iterid, status )
call grib_skip_read_only(iterid, status)
end subroutine codes_skip_read_only
!> Set the definition path
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -2796,7 +2776,6 @@ subroutine codes_set_samples_path ( path, status )
call grib_set_samples_path(path, status)
end subroutine codes_set_samples_path
subroutine codes_julian_to_datetime(jd, year, month, day, hour, minute, second, status)
real(kind=kindOfDouble), intent(in) :: jd
integer(kind=kindOfLong), intent(out) :: year, month, day, hour, minute, second
@ -2881,5 +2860,4 @@ subroutine codes_bufr_multi_element_constant_arrays_off (status )
end subroutine codes_bufr_multi_element_constant_arrays_off
end module eccodes

View File

@ -21,7 +21,6 @@ module grib_api
real(8), parameter, public :: GRIB_MISSING_DOUBLE = -1.D+100
integer(4), parameter, public :: GRIB_MISSING_LONG = 2147483647
!> Create a new message in memory from an integer or character array containting the coded message.
!>
!> The message can be accessed through its gribid and it will be available\n

View File

@ -6,7 +6,6 @@
! 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.
!> Get the distinct values of the key in argument contained in the index. The key must belong to the index.
!>
!>
@ -103,7 +102,6 @@
grib_get_real8_array
end interface grib_get
!> Get the size of an array key.
!>
!> To get the size of a key representing an array.

View File

@ -6,7 +6,6 @@
! 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.
!> Get the distinct values of the key in argument contained in the index. The key must belong to the index.
!>
!>

View File

@ -1338,7 +1338,6 @@
end if
end subroutine any_new_from_file
!> Create a new message in memory from a character array containting the coded message.
!>
!> The message can be accessed through its gribid and it will be available\n
@ -1432,7 +1431,6 @@
end if
end subroutine grib_new_from_samples
!> Free the memory for the message referred as gribid.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -1554,7 +1552,6 @@
call grib_f_check(status, caller, string)
end subroutine grib_check
!> Get latitudes/longitudes/data values (real(4)).
!>
!> Latitudes, longitudes, data values arrays are returned.
@ -2041,7 +2038,6 @@
end if
end subroutine grib_get_string
!> Get the integer array of values for a key from a grib message.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -3107,7 +3103,6 @@
end if
end subroutine grib_skip_coded
!> Skip the duplicated keys in a keys iterator.
!>
!> In case of error, if the status parameter (optional) is not given, the program will
@ -3131,7 +3126,6 @@
end if
end subroutine grib_skip_duplicates
!> Skip the read_only keys in a keys iterator.
!>
!> Read only keys cannot be set.

View File

@ -324,7 +324,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
grib_accessor_data_ccsds_packing* self = (grib_accessor_data_ccsds_packing*)a;
grib_handle* hand = grib_handle_of_accessor(a);
int err = GRIB_SUCCESS, i = 0;
int err = GRIB_SUCCESS, i = 0, is_constant_field = 0;
size_t buflen = 0;
unsigned char* buf = NULL;
@ -373,7 +373,23 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
return GRIB_SUCCESS;
}
if (bits_per_value == 0) { /* constant field */
max = val[0];
min = max;
for (i = 1; i < n_vals; i++) {
if (val[i] > max) max = val[i];
else if (val[i] < min) min = val[i];
}
if (min == max) {
is_constant_field = 1;
} else {
if (bits_per_value == 0) {
/* ECC-1202: A non-constant field with bitsPerValue==0! */
bits_per_value = 24; /* Set sane value */
}
}
if (is_constant_field) {
#ifdef DEBUG
for (i = 1; i < n_vals; i++) {
Assert(val[i] == val[0]);
@ -401,15 +417,6 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
return err;
d = grib_power(decimal_scale_factor, 10);
max = val[0];
min = max;
for (i = 1; i < n_vals; i++) {
if (val[i] > max)
max = val[i];
else if (val[i] < min)
min = val[i];
}
min *= d;
max *= d;

View File

@ -11,6 +11,7 @@
#include "grib_api_internal.h"
#include <float.h>
#define STR_EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
typedef enum
{
@ -888,8 +889,8 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
size_t count = 0;
int i;
long editionNumber;
grib_handle* outh = NULL;
grib_handle* tmp = NULL;
grib_handle* h_out = NULL;
grib_handle* h_sample = NULL;
const char* grid_type = NULL;
char name[1024];
char input_grid_type[100];
@ -919,8 +920,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
/* Get edition number from input handle */
if ((*err = grib_get_long(h, "edition", &editionNumber)) != 0) {
grib_context* c = grib_context_get_default();
if (c->write_on_fail)
grib_write_message(h, "error.grib", "w");
if (c->write_on_fail) grib_write_message(h, "error.grib", "w");
return NULL;
}
@ -1026,10 +1026,8 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
if ((*err = grib_set_values(h, values, count)) != 0) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Cannot set values %s\n", grib_get_error_message(*err));
for (i = 0; i < count; i++)
if (values[i].error)
fprintf(stderr, " %s %s\n", values[i].name, grib_get_error_message(values[i].error));
if (values[i].error) fprintf(stderr, " %s %s\n", values[i].name, grib_get_error_message(values[i].error));
goto cleanup;
}
if (h->context->debug == -1) {
@ -1090,7 +1088,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
return h;
}
} /* flags & GRIB_UTIL_SET_SPEC_FLAGS_ONLY_PACKING */
grid_type = get_grid_type_name(spec->grid_type);
if (grid_type == NULL) {
@ -1143,9 +1141,9 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
}
/* TODO: recycle tmp handle */
tmp = grib_handle_new_from_samples(NULL, name);
if (!tmp) {
/* TODO: recycle h_sample handle */
h_sample = grib_handle_new_from_samples(NULL, name);
if (!h_sample) {
*err = GRIB_INVALID_FILE;
return NULL;
}
@ -1447,6 +1445,8 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
}
/* ECC-1201: case of IEEE input ?? */
switch (packing_spec->accuracy) {
case GRIB_UTIL_ACCURACY_SAME_BITS_PER_VALUES_AS_INPUT: {
long bitsPerValue = 0;
@ -1470,7 +1470,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
default:
fprintf(stderr, "invalid packing_spec->accuracy = %ld\n", (long)packing_spec->accuracy);
grib_handle_delete(tmp);
grib_handle_delete(h_sample);
*err = GRIB_INTERNAL_ERROR;
goto cleanup;
break;
@ -1498,13 +1498,13 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
}
/* grib_write_message(h,"input.grib","w"); */
/* grib_write_message(tmp,"geo.grib","w"); */
/* copy product and local sections from h to tmp handle and store in outh */
if ((outh = grib_util_sections_copy(h, tmp, GRIB_SECTION_PRODUCT | GRIB_SECTION_LOCAL, err)) == NULL) {
/* grib_write_message(h_sample,"geo.grib","w"); */
/* copy product and local sections from h to h_sample handle and store in h_out */
if ((h_out = grib_util_sections_copy(h, h_sample, GRIB_SECTION_PRODUCT | GRIB_SECTION_LOCAL, err)) == NULL) {
goto cleanup;
}
grib_handle_delete(tmp);
grib_handle_delete(h_sample);
Assert(*err == 0);
/* Set "pl" array if provided (For reduced Gaussian grids) */
@ -1520,7 +1520,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
if (spec->pl_size != 0 && (spec->grid_type == GRIB_UTIL_GRID_SPEC_REDUCED_GG || spec->grid_type == GRIB_UTIL_GRID_SPEC_REDUCED_ROTATED_GG)) {
*err = grib_set_long_array(outh, "pl", spec->pl, spec->pl_size);
*err = grib_set_long_array(h_out, "pl", spec->pl, spec->pl_size);
if (*err) {
fprintf(stderr, "SET_GRID_DATA_DESCRIPTION: Cannot set pl %s\n", grib_get_error_message(*err));
goto cleanup;
@ -1544,32 +1544,30 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
/* Apply adjustments to bounding box if needed */
if (expandBoundingBox) {
if ((*err = expand_bounding_box(outh, values, count)) != 0) {
if ((*err = expand_bounding_box(h_out, values, count)) != 0) {
fprintf(stderr, "SET_GRID_DATA_DESCRIPTION: Cannot expand bounding box: %s\n", grib_get_error_message(*err));
if (h->context->write_on_fail)
grib_write_message(outh, "error.grib", "w");
grib_write_message(h_out, "error.grib", "w");
goto cleanup;
}
}
if (convertEditionEarlier && packing_spec->editionNumber > 1) {
*err = grib_set_long(outh, "edition", packing_spec->editionNumber);
*err = grib_set_long(h_out, "edition", packing_spec->editionNumber);
if (*err) {
fprintf(stderr, "SET_GRID_DATA_DESCRIPTION: Cannot convert to edition %ld.\n", packing_spec->editionNumber);
goto cleanup;
}
}
if ((*err = grib_set_values(outh, values, count)) != 0) {
if ((*err = grib_set_values(h_out, values, count)) != 0) {
fprintf(stderr, "SET_GRID_DATA_DESCRIPTION: Cannot set key values: %s\n", grib_get_error_message(*err));
for (i = 0; i < count; i++)
if (values[i].error)
fprintf(stderr, " %s %s\n", values[i].name, grib_get_error_message(values[i].error));
if (values[i].error) fprintf(stderr, " %s %s\n", values[i].name, grib_get_error_message(values[i].error));
goto cleanup;
}
if ((*err = grib_set_double_array(outh, "values", data_values, data_values_count)) != 0) {
if ((*err = grib_set_double_array(h_out, "values", data_values, data_values_count)) != 0) {
FILE* ferror;
size_t ii, lcount;
grib_context* c = grib_context_get_default();
@ -1588,67 +1586,66 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
fprintf(ferror, "%g }", data_values[data_values_count - 1]);
fclose(ferror);
if (c->write_on_fail)
grib_write_message(outh, "error.grib", "w");
if (c->write_on_fail) grib_write_message(h_out, "error.grib", "w");
goto cleanup;
}
/* grib_write_message(outh,"h.grib","w"); */
/* grib_write_message(h_out,"h.grib","w"); */
/* if the field is empty GRIBEX is packing as simple*/
/* if (!strcmp(input_packing_type,"grid_simple_matrix")) {
long numberOfValues;
grib_get_long(outh,"numberOfValues",&numberOfValues);
grib_get_long(h_out,"numberOfValues",&numberOfValues);
if (numberOfValues==0) {
slen=11;
grib_set_string(outh,"packingType","grid_simple",&slen);
grib_set_string(h_out,"packingType","grid_simple",&slen);
}
} */
if (grib1_high_resolution_fix) {
/* GRIB-863: must set increments to MISSING */
/* increments are not coded in message but computed */
if ((*err = grib_set_missing(outh, "iDirectionIncrement")) != 0) {
if ((*err = grib_set_missing(h_out, "iDirectionIncrement")) != 0) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Cannot set Di to missing: %s\n", grib_get_error_message(*err));
goto cleanup;
}
if ((*err = grib_set_missing(outh, "jDirectionIncrement")) != 0) {
if ((*err = grib_set_missing(h_out, "jDirectionIncrement")) != 0) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Cannot set Dj to missing: %s\n", grib_get_error_message(*err));
goto cleanup;
}
}
/*grib_dump_content(outh, stdout,"debug", ~0, NULL);*/
/*grib_dump_content(h_out, stdout,"debug", ~0, NULL);*/
/* convert to second_order if not constant field. (Also see ECC-326) */
if (setSecondOrder) {
int constant = 0;
double missingValue = 0;
grib_get_double(outh, "missingValue", &missingValue);
grib_get_double(h_out, "missingValue", &missingValue);
constant = is_constant_field(missingValue, data_values, data_values_count);
if (!constant) {
if (editionNumber == 1) {
long numberOfGroups = 0;
grib_handle* htmp = grib_handle_clone(outh);
grib_handle* htmp = grib_handle_clone(h_out);
slen = 17;
grib_set_string(htmp, "packingType", "grid_second_order", &slen);
grib_get_long(htmp, "numberOfGroups", &numberOfGroups);
/* GRIBEX is not able to decode overflown numberOfGroups with SPD */
if (numberOfGroups > 65534 && outh->context->no_spd) {
if (numberOfGroups > 65534 && h_out->context->no_spd) {
slen = 24;
grib_set_string(outh, "packingType", "grid_second_order_no_SPD", &slen);
grib_set_string(h_out, "packingType", "grid_second_order_no_SPD", &slen);
grib_handle_delete(htmp);
}
else {
grib_handle_delete(outh);
outh = htmp;
grib_handle_delete(h_out);
h_out = htmp;
}
}
else {
slen = 17;
grib_set_string(outh, "packingType", "grid_second_order", &slen);
*err = grib_set_double_array(outh, "values", data_values, data_values_count);
grib_set_string(h_out, "packingType", "grid_second_order", &slen);
*err = grib_set_double_array(h_out, "values", data_values, data_values_count);
if (*err != GRIB_SUCCESS) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: setting data values failed! %s\n", grib_get_error_message(*err));
goto cleanup;
@ -1656,21 +1653,21 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
}
else {
if (outh->context->gribex_mode_on) {
outh->context->gribex_mode_on = 0;
grib_set_double_array(outh, "values", data_values, data_values_count);
outh->context->gribex_mode_on = 1;
if (h_out->context->gribex_mode_on) {
h_out->context->gribex_mode_on = 0;
grib_set_double_array(h_out, "values", data_values, data_values_count);
h_out->context->gribex_mode_on = 1;
}
}
}
if (packing_spec->editionNumber && packing_spec->editionNumber != editionNumber) {
*err = grib_set_long(outh, "edition", packing_spec->editionNumber);
*err = grib_set_long(h_out, "edition", packing_spec->editionNumber);
if (*err != GRIB_SUCCESS) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Failed to change edition to %ld: %s\n",
packing_spec->editionNumber, grib_get_error_message(*err));
if (h->context->write_on_fail)
grib_write_message(outh, "error.grib", "w");
grib_write_message(h_out, "error.grib", "w");
goto cleanup;
}
}
@ -1679,7 +1676,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
/* ECC-353 */
/* JPEG packing is not available in GRIB edition 1 and has to be done AFTER we set data values */
if (setJpegPacking == 1) {
*err = grib_set_string(outh, "packingType", "grid_jpeg", &slen);
*err = grib_set_string(h_out, "packingType", "grid_jpeg", &slen);
if (*err != GRIB_SUCCESS) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Failed to change packingType to JPEG: %s\n",
grib_get_error_message(*err));
@ -1687,7 +1684,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
}
if (setCcsdsPacking == 1) {
*err = grib_set_string(outh, "packingType", "grid_ccsds", &slen);
*err = grib_set_string(h_out, "packingType", "grid_ccsds", &slen);
if (*err != GRIB_SUCCESS) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Failed to change packingType to CCSDS: %s\n",
grib_get_error_message(*err));
@ -1697,7 +1694,7 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
}
if (packing_spec->deleteLocalDefinition) {
grib_set_long(outh, "deleteLocalDefinition", 1);
grib_set_long(h_out, "deleteLocalDefinition", 1);
}
/* ECC-445 */
@ -1705,36 +1702,32 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
Assert(!global_grid); /* ECC-576: "global" should not be set */
}
if ((*err = check_geometry(outh, spec, data_values_count, global_grid)) != GRIB_SUCCESS) {
if ((*err = check_geometry(h_out, spec, data_values_count, global_grid)) != GRIB_SUCCESS) {
fprintf(stderr, "GRIB_UTIL_SET_SPEC: Geometry check failed! %s\n", grib_get_error_message(*err));
if (h->context->write_on_fail)
grib_write_message(outh, "error.grib", "w");
grib_write_message(h_out, "error.grib", "w");
goto cleanup;
}
/* Disable check: need to re-examine GRIB-864 */
#if 0
if ( (*err = check_handle_against_spec(outh, editionNumber, spec, global_grid)) != GRIB_SUCCESS)
{
if ( (*err = check_handle_against_spec(h_out, editionNumber, spec, global_grid)) != GRIB_SUCCESS) {
grib_context* c=grib_context_get_default();
fprintf(stderr,"GRIB_UTIL_SET_SPEC: Geometry check failed! %s\n", grib_get_error_message(*err));
if (editionNumber == 1) {
fprintf(stderr,"Note: in GRIB edition 1 latitude and longitude values cannot be represented with sub-millidegree precision.\n");
}
if (c->write_on_fail)
grib_write_message(outh,"error.grib","w");
if (c->write_on_fail) grib_write_message(h_out,"error.grib","w");
goto cleanup;
}
#endif
if (h->context->debug == -1)
fprintf(stderr, "ECCODES DEBUG: grib_util_set_spec end\n");
if (h->context->debug == -1) fprintf(stderr, "ECCODES DEBUG: grib_util_set_spec end\n");
return outh;
return h_out;
cleanup:
if (outh)
grib_handle_delete(outh);
if (h_out)
grib_handle_delete(h_out);
return NULL;
}

View File

@ -23,6 +23,7 @@ list(APPEND test_bins
gauss_sub
grib_nearest_test
grib_util_set_spec
grib_check_param_concepts
grib_local_MeteoFrance
grib_2nd_order_numValues
grib_optimize_scaling

View File

@ -32,10 +32,8 @@ ${tools_dir}/grib_set -r -s packingType=grid_ccsds $outfile1 $outfile2
${tools_dir}/grib_compare -b $BLACKLIST $outfile1 $outfile2 > $REDIRECT
templateNumber=`${tools_dir}/grib_get -p dataRepresentationTemplateNumber $outfile2`
if [ $templateNumber -ne 42 ]
then
echo dataRepresentationTemplateNumber=$templateNumber
if [ $templateNumber -ne 42 ]; then
echo "dataRepresentationTemplateNumber=$templateNumber. Should be 42!"
exit 1
fi
@ -58,7 +56,8 @@ res3=`${tools_dir}/grib_get '-F%1.2f' -p min,max,avg $outfile2`
rm -f $outfile1 $outfile2
# ECC-297
# ECC-297: Basic support
# --------------------------------------
infile=${data_dir}/tigge_ecmwf.grib2
outfile1=$infile.tmp_ccsds.1
outfile2=$infile.tmp_ccsds.2
@ -68,10 +67,21 @@ ${tools_dir}/grib_set -r -s packingType=grid_ccsds $outfile1 $outfile2
${tools_dir}/grib_compare -c data:n $outfile1 $outfile2
# ECC-477: redundant error message during conversion
# ---------------------------------------------------
infile=${data_dir}/ccsds.grib2
rm -f $outfile2
${tools_dir}/grib_set -r -s packingType=grid_simple $infile $outfile1 >$outfile2 2>&1
# there should be no error messages printed (to stdout or stderr)
[ ! -s $outfile2 ]
# ECC-1202: Check input packingType=grid_ieee
# --------------------------------------------
infile=${data_dir}/grid_ieee.grib
${tools_dir}/grib_set -r -s packingType=grid_ccsds $infile $outfile1
grib_check_key_equals $outfile1 packingType grid_ccsds
${tools_dir}/grib_set -r -s packingType=grid_simple $infile $outfile2
${tools_dir}/grib_compare -c data:n $outfile1 $outfile2
# Clean up
rm -f $outfile1 $outfile2

View File

@ -0,0 +1,143 @@
/*
* (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.
*/
/*
* Check GRIB2 parameter concept file e.g. shortName.def, paramId.def
*/
#include <assert.h>
#include "grib_api_internal.h"
typedef struct grib_expression_long {
grib_expression base;
long value;
} grib_expression_long;
typedef struct grib_expression_functor {
grib_expression base;
char* name;
grib_arguments* args;
} grib_expression_functor;
typedef struct grib_expression_string {
grib_expression base;
char* value;
} grib_expression_string;
static int type_of_surface_missing(const char* value)
{
/* Surface Type is Code Table 4.5 in which 255 is the same as missing */
if (strcmp(value, "missing") == 0 || strcmp(value, "255") == 0) {
return 1;
}
return 0;
}
static int scale_factor_missing(const char* value)
{
/* Scale factor is one octet so 255 is the same as missing */
if (strcmp(value, "missing") == 0 || strcmp(value, "255") == 0) {
return 1;
}
return 0;
}
static int grib_check_param_concepts(const char* key, const char* filename)
{
grib_concept_value* concept_value = grib_parse_concept_file(NULL, filename);
if (!concept_value)
return GRIB_IO_PROBLEM;
while (concept_value) {
grib_concept_condition* concept_condition = concept_value->conditions;
/* Convention:
* -1 key not present
* 0 key present and not missing
* 1 key present and missing
*/
int scaleFactor1Missing = -1, scaleFactor2Missing = -1;
int scaledValue1Missing = -1, scaledValue2Missing = -1;
int type1Missing = -1, type2Missing = -1;
int err = 0;
/* concept_value->name is the value of the key e.g. 151163 */
while (concept_condition) {
char condition_value[512] = {0,};
grib_expression* expression = concept_condition->expression;
const char* condition_name = concept_condition->name;
/* condition_name is discipline, parameterCategory etc. */
if (strcmp(expression->cclass->name, "long") == 0) {
grib_expression_long* el = (grib_expression_long*)expression;
sprintf(condition_value, "%ld", el->value);
}
else if (strcmp(expression->cclass->name, "functor") == 0) {
grib_expression_functor* ef = (grib_expression_functor*)expression;
sprintf(condition_value, "%s", ef->name);
}
else if (strcmp(expression->cclass->name, "string") == 0) {
grib_expression_string* es = (grib_expression_string*)expression;
sprintf(condition_value, "%s", es->value);
}
else {
Assert(0);
}
if (strcmp(condition_name, "typeOfFirstFixedSurface") == 0) {
type1Missing = type_of_surface_missing(condition_value);
}
if (strcmp(condition_name, "typeOfSecondFixedSurface") == 0) {
type2Missing = type_of_surface_missing(condition_value);
}
if (strcmp(condition_name, "scaleFactorOfFirstFixedSurface") == 0) {
scaleFactor1Missing = scale_factor_missing(condition_value);
}
if (strcmp(condition_name, "scaleFactorOfSecondFixedSurface") == 0) {
scaleFactor2Missing = scale_factor_missing(condition_value);
}
if (strcmp(condition_name, "scaledValueOfFirstFixedSurface") == 0) {
scaledValue1Missing = (strcmp(condition_value, "missing") == 0);
}
if (strcmp(condition_name, "scaledValueOfSecondFixedSurface") == 0) {
scaledValue2Missing = (strcmp(condition_value, "missing") == 0);
}
concept_condition = concept_condition->next;
}
/* Now check the scale factor/value pairs */
if (type1Missing == 1 && scaleFactor1Missing == 0 && scaledValue1Missing == 0) err = 1;
if (type2Missing == 1 && scaleFactor2Missing == 0 && scaledValue2Missing == 0) err = 1;
if (scaleFactor1Missing == 1 && scaledValue1Missing == 0) err = 1;
if (scaleFactor1Missing == 0 && scaledValue1Missing == 1) err = 1;
if (scaleFactor2Missing == 1 && scaledValue2Missing == 0) err = 1;
if (scaleFactor2Missing == 0 && scaledValue2Missing == 1) err = 1;
if (err) {
fprintf(stderr,
"Error: Mismatched type of surface, scale factor, scaled value keys for %s='%s'.\n"
" If the type of surface is missing so should its scaled keys\n"
" If the scale factor is missing so should the scaled value and vice versa\n",
key, concept_value->name);
return GRIB_INVALID_KEY_VALUE;
}
concept_value = concept_value->next;
}
return GRIB_SUCCESS;
}
int main(int argc, char** argv)
{
int err = 0;
const char* concepts_key = argv[1];
const char* concepts_filename = argv[2];
assert(argc == 3);
err = grib_check_param_concepts(concepts_key, concepts_filename);
if (err) return err;
printf("ALL OK\n");
return 0;
}

View File

@ -10,12 +10,21 @@
. ./include.sh
REDIRECT=/dev/null
# This script will check the following concept files:
# name.def paramId.def shortName.def units.def cfVarName.def
#
# Do various checks on the concepts files
#
# First check the GRIB2 paramId.def and shortName.def
# ----------------------------------------------------
$EXEC ${test_dir}/grib_check_param_concepts paramId $ECCODES_DEFINITION_PATH/grib2/paramId.def
$EXEC ${test_dir}/grib_check_param_concepts paramId $ECCODES_DEFINITION_PATH/grib2/localConcepts/ecmf/paramId.def
$EXEC ${test_dir}/grib_check_param_concepts shortName $ECCODES_DEFINITION_PATH/grib2/shortName.def
$EXEC ${test_dir}/grib_check_param_concepts shortName $ECCODES_DEFINITION_PATH/grib2/localConcepts/ecmf/shortName.def
# Check the group: name.def paramId.def shortName.def units.def cfVarName.def
# ----------------------------------------------------------------------------
# Check whether the Test::More Perl module is available
set +e
perl -e 'use Test::More;'

View File

@ -1475,7 +1475,6 @@ static void test_concept_condition_strings()
err = get_concept_condition_string(h, "gridType", NULL, result);
Assert(!err);
/*printf("%s\n", result);*/
Assert(strcmp(result, "gridDefinitionTemplateNumber=0,PLPresent=0") == 0);
err = get_concept_condition_string(h, "stepType", NULL, result);