mirror of https://github.com/ecmwf/eccodes.git
UERRA: Merge changes from Mladek's tigge_check_uerra branch
This commit is contained in:
parent
eb6b68329b
commit
68257583d8
|
@ -86,9 +86,10 @@ int valueflg = 0;
|
|||
const char* param = "unknown";
|
||||
int warnflg = 0;
|
||||
int zeroflg = 0;
|
||||
int is_lam =0;
|
||||
int is_s2s =0;
|
||||
int is_s2s_refcst =0;
|
||||
int is_lam = 0;
|
||||
int is_s2s = 0;
|
||||
int is_s2s_refcst = 0;
|
||||
int is_uerra = 0;
|
||||
|
||||
const char* good = NULL;
|
||||
const char* bad = NULL;
|
||||
|
@ -403,21 +404,14 @@ static void point_in_time(grib_handle* h,const parameter* p,double min,double ma
|
|||
break;
|
||||
}
|
||||
|
||||
if (!is_lam)
|
||||
if (is_uerra)
|
||||
{
|
||||
if(get(h,"indicatorOfUnitOfTimeRange") == 11) /* six hours */
|
||||
if(get(h,"indicatorOfUnitOfTimeRange") == 1) /* hourly */
|
||||
{
|
||||
/* Six hourly is OK */
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(eq(h,"indicatorOfUnitOfTimeRange",1));/* Hours */
|
||||
CHECK((get(h,"forecastTime") % 6) == 0); /* Every six hours */
|
||||
CHECK((eq(h,"forecastTime",1)||eq(h,"forecastTime",2)||eq(h,"forecastTime",4)||eq(h,"forecastTime",5))||(get(h,"forecastTime") % 3) == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (is_lam) {
|
||||
if(get(h,"indicatorOfUnitOfTimeRange") == 10 ) /* three hours */
|
||||
{
|
||||
/* Three hourly is OK */
|
||||
|
@ -428,6 +422,17 @@ static void point_in_time(grib_handle* h,const parameter* p,double min,double ma
|
|||
CHECK(eq(h,"indicatorOfUnitOfTimeRange",1));/* Hours */
|
||||
CHECK((get(h,"forecastTime") % 3) == 0); /* Every three hours */
|
||||
}
|
||||
} else {
|
||||
if(get(h,"indicatorOfUnitOfTimeRange") == 11) /* six hours */
|
||||
{
|
||||
/* Six hourly is OK */
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(eq(h,"indicatorOfUnitOfTimeRange",1));/* Hours */
|
||||
CHECK((get(h,"forecastTime") % 6) == 0); /* Every six hours */
|
||||
}
|
||||
}
|
||||
|
||||
check_range(h,p,min,max);
|
||||
|
@ -513,6 +518,10 @@ static void statistical_process(grib_handle* h,const parameter* p,double min,dou
|
|||
{
|
||||
switch(get(h,"typeOfProcessedData"))
|
||||
{
|
||||
case 0: /* UERRA Analysis xxx double check!! */
|
||||
CHECK(eq(h,"productDefinitionTemplateNumber",0));
|
||||
break;
|
||||
|
||||
case 2: /* Analysis and forecast products */
|
||||
CHECK(eq(h,"productDefinitionTemplateNumber",8));
|
||||
break;
|
||||
|
@ -647,8 +656,11 @@ static void from_start(grib_handle* h,const parameter* p,double min,double max)
|
|||
statistical_process(h,p,min,max);
|
||||
CHECK(eq(h,"startStep",0));
|
||||
|
||||
if(step == 0)
|
||||
CHECK(min == 0 && max == 0);
|
||||
if(step == 0){
|
||||
if(!is_uerra){
|
||||
CHECK(min == 0 && max == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
check_range(h,p,min/step,max/step);
|
||||
|
@ -1028,28 +1040,42 @@ static void verify(grib_handle* h)
|
|||
CHECK(eq(h,"second",0));
|
||||
CHECK(ge(h,"startStep",0));
|
||||
|
||||
if (!is_s2s){
|
||||
CHECK(eq(h,"productionStatusOfProcessedData",4)||eq(h,"productionStatusOfProcessedData",5)); /* TIGGE prod||test */
|
||||
CHECK(le(h,"endStep",30*24));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_s2s){
|
||||
CHECK(eq(h,"productionStatusOfProcessedData",6)||eq(h,"productionStatusOfProcessedData",7)); /* S2S prod||test */
|
||||
CHECK(le(h,"endStep",100*24));
|
||||
}
|
||||
|
||||
if (!is_lam){
|
||||
CHECK((get(h,"step") % 6) == 0);
|
||||
else if (is_uerra){
|
||||
CHECK(eq(h,"productionStatusOfProcessedData",9)||eq(h,"productionStatusOfProcessedData",10)); /* UERRA prod||test */
|
||||
CHECK(le(h,"endStep",30));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK((get(h,"step") % 3) == 0);
|
||||
CHECK(eq(h,"productionStatusOfProcessedData",4)||eq(h,"productionStatusOfProcessedData",5)); /* TIGGE prod||test */
|
||||
CHECK(le(h,"endStep",30*24));
|
||||
}
|
||||
|
||||
/* 2 = analysis or forecast , 3 = control forecast, 4 = perturbed forecast */
|
||||
CHECK(eq(h,"typeOfProcessedData",2)||eq(h,"typeOfProcessedData",3)||eq(h,"typeOfProcessedData",4));
|
||||
if (is_uerra){
|
||||
CHECK((eq(h,"step",1)||eq(h,"step",2)||eq(h,"step",4)||eq(h,"step",5))||(get(h,"step") % 3) == 0);
|
||||
}
|
||||
else if (is_lam){
|
||||
CHECK((get(h,"step") % 3) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK((get(h,"step") % 6) == 0);
|
||||
}
|
||||
|
||||
/* TODO: validate local usage. Empty for now */
|
||||
if (is_uerra){
|
||||
/* 0 = analysis , 2 = analysis or forecast */
|
||||
CHECK(eq(h,"typeOfProcessedData",0)||eq(h,"typeOfProcessedData",2));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 2 = analysis or forecast , 3 = control forecast, 4 = perturbed forecast */
|
||||
CHECK(eq(h,"typeOfProcessedData",2)||eq(h,"typeOfProcessedData",3)||eq(h,"typeOfProcessedData",4));
|
||||
}
|
||||
|
||||
/* TODO: validate local usage. Empty for now xxx*/
|
||||
/* CHECK(eq(h,"section2.sectionLength",5)); */
|
||||
|
||||
/* Section 3 */
|
||||
|
@ -1063,6 +1089,11 @@ static void verify(grib_handle* h)
|
|||
latlon_grid(h);
|
||||
break;
|
||||
|
||||
case 30: /*Lambert conformal*/
|
||||
/*lambert_grid(h); # TODO xxx*/
|
||||
printf("Lambert grid - geometry checking not implemented yet!\n");
|
||||
break;
|
||||
|
||||
case 40: /* gaussian grid (regular or reduced) */
|
||||
gaussian_grid(h);
|
||||
break;
|
||||
|
@ -1227,6 +1258,10 @@ int main(int argc, char** argv)
|
|||
is_s2s_refcst=1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
is_uerra=1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
|
|
@ -1762,7 +1762,7 @@ warning: s2s.z_tigge_c_kwbc_20090829000000_ncep_prod_pf_sl_0024_003_0000_tcw.gri
|
|||
},
|
||||
|
||||
/*
|
||||
s2s/rums warning: s2s.z_s2s_c_rhmc_20150819000000_glob_prod_0336_017.sl.grib2, field 4 [surface_air_temperature_sfc.glob]: surface_air_temperature_sfc.glob minimum value 177.17 is not in [180,290]
|
||||
s2s/rums warning: s2s.z_s2s_c_rhmc_20150819000000_glob_prod_0336_017.sl.grib2, field 4 [surface_air_temperature_sfc.glob]: surface_air_temperature_sfc.glob minimum value 177.17 is not in [180,290]
|
||||
s2s/ammc: warning: s2s.2t_20151224_26.grib2, field 12 [surface_air_temperature_sfc.glob.s2]: surface_air_temperature_sfc.glob.s2 maximum value 353.017 is not in [270,350]
|
||||
*/
|
||||
|
||||
|
@ -2309,5 +2309,75 @@ s2s/ammc/enfo:s2s.tcc_20151004_9.grib2, field 21 [total_cloud_cover_sfc.glob]: t
|
|||
{&daily_average, &predefined_level},
|
||||
},
|
||||
|
||||
/* UERRA */
|
||||
{
|
||||
"total_cloud_cover_sfc.ur",
|
||||
0,
|
||||
1e-10,
|
||||
0.9999,
|
||||
100.00001,
|
||||
{
|
||||
{"class", GRIB_TYPE_STRING, 0, "ur"},
|
||||
{"discipline", GRIB_TYPE_LONG, 0},
|
||||
{"parameterCategory", GRIB_TYPE_LONG, 6},
|
||||
{"parameterNumber", GRIB_TYPE_LONG, 1},
|
||||
{"typeOfFirstFixedSurface", GRIB_TYPE_LONG, 1},
|
||||
{"typeOfSecondFixedSurface", GRIB_TYPE_LONG, 8},
|
||||
{NULL, },
|
||||
},
|
||||
{&point_in_time, &predefined_thickness},
|
||||
},
|
||||
{
|
||||
"high_cloud_cover_sfc.ur",
|
||||
0,
|
||||
1e-10,
|
||||
0.9999,
|
||||
100.00001,
|
||||
{
|
||||
{"class", GRIB_TYPE_STRING, 0, "ur"},
|
||||
{"discipline", GRIB_TYPE_LONG, 0},
|
||||
{"parameterCategory", GRIB_TYPE_LONG, 6},
|
||||
{"parameterNumber", GRIB_TYPE_LONG, 5},
|
||||
{"typeOfFirstFixedSurface", GRIB_TYPE_LONG, 1},
|
||||
{"typeOfSecondFixedSurface", GRIB_TYPE_LONG, 8},
|
||||
{NULL, },
|
||||
},
|
||||
{&point_in_time, &predefined_thickness},
|
||||
},
|
||||
{
|
||||
"medium_cloud_cover_sfc.ur",
|
||||
0,
|
||||
1e-10,
|
||||
0.9999,
|
||||
100.00001,
|
||||
{
|
||||
{"class", GRIB_TYPE_STRING, 0, "ur"},
|
||||
{"discipline", GRIB_TYPE_LONG, 0},
|
||||
{"parameterCategory", GRIB_TYPE_LONG, 6},
|
||||
{"parameterNumber", GRIB_TYPE_LONG, 4},
|
||||
{"typeOfFirstFixedSurface", GRIB_TYPE_LONG, 1},
|
||||
{"typeOfSecondFixedSurface", GRIB_TYPE_LONG, 8},
|
||||
{NULL, },
|
||||
},
|
||||
{&point_in_time, &predefined_thickness},
|
||||
},
|
||||
{
|
||||
"low_cloud_cover_sfc.ur",
|
||||
0,
|
||||
1e-10,
|
||||
0.9999,
|
||||
100.00001,
|
||||
{
|
||||
{"class", GRIB_TYPE_STRING, 0, "ur"},
|
||||
{"discipline", GRIB_TYPE_LONG, 0},
|
||||
{"parameterCategory", GRIB_TYPE_LONG, 6},
|
||||
{"parameterNumber", GRIB_TYPE_LONG, 3},
|
||||
{"typeOfFirstFixedSurface", GRIB_TYPE_LONG, 1},
|
||||
{"typeOfSecondFixedSurface", GRIB_TYPE_LONG, 8},
|
||||
{NULL, },
|
||||
},
|
||||
{&point_in_time, &predefined_thickness},
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -40,126 +40,126 @@ int unique = 0;
|
|||
|
||||
static void check(const char* name,int a)
|
||||
{
|
||||
if(!a) {
|
||||
fprintf(stderr,"%s, field %d [%s]: %s failed\n",file,field,param,name);
|
||||
exit(1);
|
||||
}
|
||||
if(!a) {
|
||||
fprintf(stderr,"%s, field %d [%s]: %s failed\n",file,field,param,name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static long get(grib_handle *h,const char* what)
|
||||
{
|
||||
int e; long val;
|
||||
if((e = grib_get_long(h,what,&val)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
val = -1;
|
||||
}
|
||||
return val;
|
||||
int e; long val;
|
||||
if((e = grib_get_long(h,what,&val)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
val = -1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static char* sget(grib_handle *h,const char* what,char* val,size_t size)
|
||||
{
|
||||
int e;
|
||||
if((e = grib_get_string(h,what,val,&size)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
}
|
||||
return val;
|
||||
int e;
|
||||
if((e = grib_get_string(h,what,val,&size)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
static double dget(grib_handle *h,const char* what)
|
||||
{
|
||||
int e; double val;
|
||||
if((e = grib_get_double(h,what,&val)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
val = -1;
|
||||
}
|
||||
return val;
|
||||
int e; double val;
|
||||
if((e = grib_get_double(h,what,&val)) != GRIB_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"%s, field %d [%s]: cannot get %s: %s\n",file,field,param,what,grib_get_error_message(e));
|
||||
exit(1);
|
||||
val = -1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static int missing(grib_handle *h,const char* what)
|
||||
{
|
||||
int err=0;
|
||||
return grib_is_missing(h,what,&err);
|
||||
int err=0;
|
||||
return grib_is_missing(h,what,&err);
|
||||
}
|
||||
|
||||
static int eq(grib_handle *h,const char* what,long value)
|
||||
{
|
||||
return get(h,what) == value;
|
||||
return get(h,what) == value;
|
||||
}
|
||||
|
||||
static int ne(grib_handle *h,const char* what,long value)
|
||||
{
|
||||
return get(h,what) != value;
|
||||
return get(h,what) != value;
|
||||
}
|
||||
|
||||
static int ge(grib_handle *h,const char* what,long value)
|
||||
{
|
||||
return get(h,what) >= value;
|
||||
return get(h,what) >= value;
|
||||
}
|
||||
*/
|
||||
|
||||
static void split(grib_handle *h)
|
||||
{
|
||||
char wmo_name[1024];
|
||||
char origin[80];
|
||||
char model[80];
|
||||
char expver[80];
|
||||
char levtype[80];
|
||||
char type[80];
|
||||
char tigge_name[80];
|
||||
char wmo_name[1024];
|
||||
char origin[80];
|
||||
char model[80];
|
||||
char expver[80];
|
||||
char levtype[80];
|
||||
char type[80];
|
||||
char tigge_name[80];
|
||||
|
||||
long level = 0;
|
||||
long number = 0;
|
||||
long level = 0;
|
||||
long number = 0;
|
||||
|
||||
size_t size;
|
||||
const void* buffer;
|
||||
FILE *f;
|
||||
size_t size;
|
||||
const void* buffer;
|
||||
FILE *f;
|
||||
|
||||
sget(h,"type",type,sizeof(type));
|
||||
sget(h,"levtype",levtype,sizeof(levtype));
|
||||
sget(h,"type",type,sizeof(type));
|
||||
sget(h,"levtype",levtype,sizeof(levtype));
|
||||
|
||||
if(strcmp(type,"fc") != 0)
|
||||
number = get(h,"number");
|
||||
if(strcmp(type,"fc") != 0)
|
||||
number = get(h,"number");
|
||||
|
||||
if(strcmp(levtype,"sfc") == 0)
|
||||
strcpy(levtype,"sl");
|
||||
else
|
||||
level = get(h,"level");
|
||||
if(strcmp(levtype,"sfc") == 0)
|
||||
strcpy(levtype,"sl");
|
||||
else
|
||||
level = get(h,"level");
|
||||
|
||||
sprintf(wmo_name,"z_tigge_c_%s_%08ld%04ld00_%s_%s_%s_%s_%04ld_%03ld_%04ld_%s.grib",
|
||||
sget(h,"origin",origin,sizeof(origin)),
|
||||
get(h,"date"),
|
||||
get(h,"time"),
|
||||
sget(h,"model",model,sizeof(model)),
|
||||
sget(h,"expver",expver,sizeof(expver)),
|
||||
type,
|
||||
levtype,
|
||||
get(h,"endStep"),
|
||||
number,
|
||||
level,
|
||||
sget(h,"tigge_short_name",tigge_name,sizeof(tigge_name))
|
||||
sprintf(wmo_name,"z_tigge_c_%s_%08ld%04ld00_%s_%s_%s_%s_%04ld_%03ld_%04ld_%s.grib",
|
||||
sget(h,"origin",origin,sizeof(origin)),
|
||||
get(h,"date"),
|
||||
get(h,"time"),
|
||||
sget(h,"model",model,sizeof(model)),
|
||||
sget(h,"expver",expver,sizeof(expver)),
|
||||
type,
|
||||
levtype,
|
||||
get(h,"endStep"),
|
||||
number,
|
||||
level,
|
||||
sget(h,"tigge_short_name",tigge_name,sizeof(tigge_name))
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
if(print_names) printf("%s\n",wmo_name);
|
||||
if(print_names) printf("%s\n",wmo_name);
|
||||
|
||||
if(unique)
|
||||
{
|
||||
if(access(wmo_name,F_OK) == 0)
|
||||
{
|
||||
fprintf(stderr,"tigge_split: %s already exists\n",wmo_name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(unique)
|
||||
{
|
||||
if(access(wmo_name,F_OK) == 0)
|
||||
{
|
||||
fprintf(stderr,"tigge_split: %s already exists\n",wmo_name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
f = fopen(wmo_name,"w");
|
||||
if(!f) { perror(wmo_name); exit(1); }
|
||||
f = fopen(wmo_name,"w");
|
||||
if(!f) { perror(wmo_name); exit(1); }
|
||||
|
||||
CHECK(grib_get_message(h,&buffer,&size) == 0);
|
||||
|
||||
|
@ -168,83 +168,83 @@ static void split(grib_handle *h)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if(fclose(f)) { perror(wmo_name); exit(1); }
|
||||
if(fclose(f)) { perror(wmo_name); exit(1); }
|
||||
}
|
||||
|
||||
static void validate(const char* path)
|
||||
{
|
||||
FILE *f = fopen(path,"r");
|
||||
grib_handle *h = 0;
|
||||
int err;
|
||||
int count = 0;
|
||||
FILE *f = fopen(path,"r");
|
||||
grib_handle *h = 0;
|
||||
int err;
|
||||
int count = 0;
|
||||
|
||||
if(!f) {
|
||||
fprintf(stderr,"%s: %s\n",path,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if(!f) {
|
||||
fprintf(stderr,"%s: %s\n",path,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while( (h= grib_handle_new_from_file(0,f,&err)) != NULL)
|
||||
{
|
||||
++field;
|
||||
split(h);
|
||||
grib_handle_delete(h);
|
||||
count++;
|
||||
param = "unknown";
|
||||
}
|
||||
fclose(f);
|
||||
while( (h= grib_handle_new_from_file(0,f,&err)) != NULL)
|
||||
{
|
||||
++field;
|
||||
split(h);
|
||||
grib_handle_delete(h);
|
||||
count++;
|
||||
param = "unknown";
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if(err) {
|
||||
fprintf(stderr,"%s: grib_handle_new_from_file: %s\n",path,grib_get_error_message(err));
|
||||
exit(1);
|
||||
}
|
||||
if(err) {
|
||||
fprintf(stderr,"%s: grib_handle_new_from_file: %s\n",path,grib_get_error_message(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(count == 0) {
|
||||
fprintf(stderr,"%s does not contain any GRIBs\n",path);
|
||||
exit(1);
|
||||
}
|
||||
if(count == 0) {
|
||||
fprintf(stderr,"%s does not contain any GRIBs\n",path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage()
|
||||
{
|
||||
printf("tigge_split [-p] files ....\n");
|
||||
printf(" -p: print names of files created\n");
|
||||
exit(1);
|
||||
printf("tigge_split [-p] files ....\n");
|
||||
printf(" -p: print names of files created\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc,const char** argv)
|
||||
{
|
||||
int i = 1;
|
||||
int i = 1;
|
||||
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
if(argv[i][0] == '-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case 'p':
|
||||
print_names++;
|
||||
break;
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
if(argv[i][0] == '-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case 'p':
|
||||
print_names++;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
unique++;
|
||||
break;
|
||||
case 'u':
|
||||
unique++;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == argc)
|
||||
usage();
|
||||
if(i == argc)
|
||||
usage();
|
||||
|
||||
for(; i < argc; i++)
|
||||
validate(argv[i]);
|
||||
for(; i < argc; i++)
|
||||
validate(argv[i]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue