From 68257583d82ac0d06ecdf5ccbc5de2df07028fe5 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 23 May 2016 18:43:42 +0100 Subject: [PATCH] UERRA: Merge changes from Mladek's tigge_check_uerra branch --- tigge/tigge_check.c | 93 +++++++++++----- tigge/tigge_check.h | 72 +++++++++++- tigge/tigge_split.c | 266 ++++++++++++++++++++++---------------------- 3 files changed, 268 insertions(+), 163 deletions(-) diff --git a/tigge/tigge_check.c b/tigge/tigge_check.c index f0ac9961e..21ec988b0 100755 --- a/tigge/tigge_check.c +++ b/tigge/tigge_check.c @@ -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; diff --git a/tigge/tigge_check.h b/tigge/tigge_check.h index 2a43aa99f..3c150fe59 100644 --- a/tigge/tigge_check.h +++ b/tigge/tigge_check.h @@ -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}, + } + }; diff --git a/tigge/tigge_split.c b/tigge/tigge_split.c index 6cbbb6361..1f59ac53b 100755 --- a/tigge/tigge_split.c +++ b/tigge/tigge_split.c @@ -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; }