/* * Copyright(c) 2007, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: Mcgrb2dec.c,v 1.15 2017/10/26 17:52:40 kevinb Tst $ ****/ #include #include #include #include #include #include #include "mcidas.h" #include "mcidasp.h" #include "mcgrib.h" #include "mcgrib2.h" #include "bufr.h" #include "xcd.h" /* We use the MySQL_INSTALLED variable in macro 'ifdef' statements to block out calls to MySQL libary functions because MySQL may not be installed on the system. If MySQL is installed and will be used for the GRIB database then the MySQL_INSTALLED environment variable will have been set during installation and will contain the path to the MySQL installation. */ #ifdef MySQL_INSTALLED #include #define QUERY_LEN 2048 int McMySQLPutGrib2( char*, long int, long int, int, g2int*, g2int*, Fint*, gribfield*); #endif static int Mcgrib2tofilename (g2int*,Fint*, int, GB2NAVTAB*, char**, int,int,NODECODE*); int getModelStr (int, char*); int Mcgrb2decoder (unsigned char*, int, int, int,char*,FsLen); int GetGrib2ProjectionNames(g2int, Fint*, char[],char[]); int GetForecastDayTime( int, int, int, int*, int* ); enum {GRIB, BUFR}; /*********************************************************** ** ** FORTRAN wrapper */ Fint mcgrb2dec_ (Fint4 *buffer, Fint4 *nbytes, Fint4 *file_name_format, Fint4 *decode_type, char *no_dec_file,FsLen file_len) { return Mcgrb2decoder ((unsigned char *)buffer, *nbytes, *file_name_format, *decode_type, no_dec_file,file_len); } /***********************************************************/ int Mcgrb2decoder (unsigned char *buffer, int buf_len, int file_name_format, int decode_type,char* no_dec_file,FsLen file_len) { unsigned char *buf_ptr; /* pointer to buffer */ char ctmp[255]; /* temp character string */ int msg_type = -1; /* GRIB or BUFR */ int msg_len; /* length of message in bytes */ int temp; /* place-holder for reading data */ int i,j; /* loop control variables */ int search_len; /* len of section of buffer to be searched */ int ok; /* return status variable */ static short int first_call = 1; /* flag, 1 if first call to routine */ g2int indSection[3]; g2int idSection[13]; g2int numFields; g2int numLocal; g2int templateNum; gribfield *grb2fld; Fint *GridNav; int unpack = 0; /* flag to unpack GRIB-2 data via g2_getfld is zero becasue we just need metadata for the database */ int expand; /* parameter ignored when unpack=0 but need as a placeholder */ int ScanMode; int ierr; int LevUnit; int LevScale; int Fhour; int yearday; int hhmmss; double Lev1, Lev2; int Lev1Type, Lev2Type; int levelType; /* level type to show in database */ int ModelName; char strModelName[10]; int ParString4; int UString4; int ensembleString; int Scale; int processID; char * LongParString; char * LongUnitString; FILE *file_ptr; /* pointer to GRIB/BUFR file */ char *filename; /* name of file */ char full_path[L_SIZE]; /* name of file with full path */ const char *path_ptr; long int ptr_to_grid; /* beg byte offset of grid in GRIB file */ long int grid_size; /* size of grid in bytes */ char model_name[5]; /* 3-4 character model name */ int using_grib_database = 0; /* flag to tell whether the GRIB database is being used */ char* t_file; static int n_no_decode; /* Number of no decode entries from NOGRIB.CFG */ static NODECODE *no_dec = NULL; /* list of grib messages not to be decoded after PDS section*/ static int n_gb2nav; /* Number of GRIB2 navigation table entries */ static GB2NAVTAB *gb2navtab = NULL; /* list of available navigation for a model type */ /* allocate memory for GRIB 2 data */ if (first_call) { first_call = 0; t_file=fsalloc(no_dec_file,file_len); if (strcmp(no_dec_file,"")!=0) { no_dec_file[80]='\0'; ok = load_no_decode_grb2 (t_file , &n_no_decode , &no_dec); } free(t_file); ok = load_gb2navtab(&n_gb2nav, &gb2navtab); Mcprintf("Loaded %i nav table entries\n",n_gb2nav); #ifdef MySQL_INSTALLED Mceprintf("Using MySQL database for GRIB-2\n"); #else Mceprintf("Not using MySQL database for GRIB-2\n"); #endif } /* If in this function, we know it is 'GRIB' */ search_len = buf_len - 4; buf_ptr = buffer; /* Return if we are only decoding BUFR data*/ if ( decode_type == 3 ) return (0); /* Decode the Indicator and Identification Sections */ ok=g2_info(buf_ptr,indSection,idSection,&numFields,&numLocal); if (ok != 0) { switch(ok) { case 1: Mcprintf("DMBIN (GRIB-2): g2_info error %i: Beginning characters GRIB not found!\n",ok); break; case 3: Mcprintf("DMBIN (GRIB-2): g2_info error %i: Could not find Section 1 (Identification Section)\n",ok); break; case 4: Mcprintf("DMBIN (GRIB-2): g2_info error %i: '7777' found but not where expected!\n",ok); break; case 5: Mcprintf("DMBIN (GRIB-2): g2_info error %i: '7777' not found at end of GRIB message!\n",ok); break; case 6: Mcprintf("DMBIN (GRIB-2): g2_info error %i: Invalid section number found in GRIB message!\n",ok); break; default: Mcprintf("DMBIN (GRIB-2): g2_info error %i\n",ok); } return (-5); } ok = M0Grib2MakeTime(&idSection[0],&yearday,&hhmmss); if (numFields > 2) { Mcprintf("Number of fields cannot be greater than 2!\n"); return (-400); } /*GridNav = (Fint *)malloc(sizeof(Fint)*64); if (GridNav == (Fint *)NULL) return(-50); memset(GridNav,0,64*sizeof(Fint));*/ for (j=0; j< numFields; j++) { ok=g2_getfld(buf_ptr,j+1,unpack,expand,&grb2fld); if (ok != 0) { Mcprintf("DMBIN (GRIB-2): g2_getfld fails!\n"); g2_free(grb2fld); return (-6); } ok = M0GetNavFromGribTemplate(grb2fld->igdtnum, &grb2fld->igdtmpl[0],&GridNav,&ScanMode); if (ok != 0) { templateNum=grb2fld->igdtnum; g2_free(grb2fld); /* Currently do not support template 10, true Mercator */ if (templateNum ==10){ /*Mcprintf("DMBIN (GRIB-2): True Mercator Template 10 not supported!\n");*/ return(0); } /* Currently do not support template 40, Gaussian Lat/Lon */ else if (templateNum ==40){ /*Mcprintf("DMBIN (GRIB-2): Gaussian Latitude/Longitude Template 40 not supported!\n");*/ return(0); } /* Write out unsupported navigation data to a file before exiting */ file_ptr = (FILE *) NULL; path_ptr = Mcpathname ("naverror.grb2"); if (path_ptr) { (void) strcpy (full_path , path_ptr); file_ptr = fopen (full_path, "a"); } if ( file_ptr == (FILE *) NULL ) { Mcprintf("not writing out test file!\n"); return (-7); } /* Write the information to the GRIB/BUFR file */ ptr_to_grid = ftell(file_ptr); fwrite(buffer, sizeof(char), buf_len, file_ptr); fclose(file_ptr); Mcprintf("DMBIN (GRIB-2): M0GetNavFromGribTemplate fails with OK=%d, templateNum=%d!\n",ok,templateNum); return (-12); } switch (grb2fld->ipdtnum) { case 0: case 1: case 2: case 5: case 8: case 9: case 11: case 12: ok = M0GetProductInfoTemplate(grb2fld->ipdtnum,&grb2fld->ipdtmpl[0], idSection[0],idSection[1],indSection[0], &LongParString, &ParString4, &LongUnitString, &UString4, &Lev1, &Lev2, &Lev1Type, &Lev2Type,&LevUnit,&LevScale, &ModelName, &Fhour, &processID,&ensembleString); if (ok != 0) { if (ok==-1) Mcprintf("DMBIN (GRIB-2): Parameter not in GRIB-2 parameter table!\n"); else Mcprintf("DMBIN (GRIB-2): M0GetProductInfoTemplate fails (value=%d) where grb2fld->ipdtnum=%d, GenCenter=%d\n",ok,grb2fld->ipdtnum,idSection[0]); g2_free(grb2fld); free(GridNav); return (-10); } break; default: Mcprintf("Product Definition Template %d is currently not supported in McIDAS\n",grb2fld->ipdtnum); g2_free(grb2fld); free(GridNav); return(-10); break; } /*if (Lev1Type == Lev2Type)*/ levelType = Lev1Type; /* Hard-code this in - otherwise MOS are not (currently) identifiable */ if (idSection[0]==7 && idSection[1]==14 && processID == 0){ char *mosModel="MOS "; memcpy(&GridNav[32], mosModel, 4); } else (void) memmove(&GridNav[32], (char*)&ModelName, sizeof(char)*4); (void) memmove(&GridNav[6], (char*)&ParString4, sizeof(char)*4); (void) memmove(&GridNav[8], (char*)&UString4, sizeof(char)*4); (void) memmove(&GridNav[11], (char*)&LevUnit, sizeof(char)*4); (void) memmove(&GridNav[19], (char*)&ensembleString, sizeof(char)*4); (void) memmove(&GridNav[52], (const char*)&LongParString[0], sizeof(char)*48); GridNav[9] = (int)Lev1; GridNav[10] = LevScale; GridNav[5] = Fhour; if (Lev2 != 0.0) { GridNav[12] = 8; GridNav[14] = (int)Lev2; } GridNav[3] = yearday; GridNav[4] = hhmmss; GridNav[7] = 5 - Scale; GridNav[49]= processID; /* Create the file name */ filename = malloc (256 * sizeof (char)); /* Determine the name for the GRIB file */ ok = Mcgrib2tofilename (&idSection[0],&GridNav[0],n_gb2nav,gb2navtab,&filename,file_name_format,n_no_decode,no_dec); if ( ok < 0 ) { free(filename); free(GridNav); g2_free(grb2fld); /* -20 means the GRIB is not being decoded according to NOGRIB.CFG */ /* So, this is not an error to be sent back to the data monitor */ if (ok == -20) return(0); return (-11); } /* get the path to the file */ file_ptr = (FILE *) NULL; path_ptr = Mcpathname (filename); if (path_ptr) { (void) strcpy (full_path , path_ptr); file_ptr = fopen (full_path, "a"); } if ( file_ptr == (FILE *) NULL ) { free(filename); free(GridNav); g2_free(grb2fld); return (-7); } /* Write the information to the GRIB/BUFR file */ ptr_to_grid = ftell(file_ptr); fwrite(buffer, sizeof(char), buf_len, file_ptr); grid_size = ftell(file_ptr) - ptr_to_grid - 1; fclose(file_ptr); #ifdef MySQL_INSTALLED /* Create a new record in the GRIB database */ /* Add GRIB information to database */ ok = McMySQLPutGrib2(full_path, ptr_to_grid, grid_size, levelType, &indSection[0], &idSection[0], &GridNav[0],&grb2fld[0]); if (ok < 0) { Mcprintf("Could not write to GRIB database (%i)\n", ok); } #endif free(GridNav); g2_free(grb2fld); free (filename); } /* end for (j=0; j< numFields; j++) */ if (ok < 0) { /* If OK negative when we hit here, it is a problem with writing to the database */ Mcprintf("Problem with writing to the MySQL database, ok = %i!\n",ok); return (-13); } return (0); } #ifdef MySQL_INSTALLED /***************************************************************** ** Name: ** McMySQLPutGrib2 - writes grid information to a MYSQL database ** ** Interface: ** int ** McMYSQLPut (char *filename, ** long int ptr_to_grid, ** long int grid_size, ** g2int *indSection, ** g2int *idSection, ** Fint *GridNav ** gribfield *grb2fld * ) ** ** Input: ** filename - GRIB file name ** ptr_to_grid - byte offset to beginning of grid ** grid_size - size of grid in bytes ** indSection - pointer to indicator section of GRIB-2 file ** idSection - pointer to identification section of GRIB-2 file ** GridNav - pointer to McIDAS header information ** grb2fld - pointer to GRIB-2 information ** ** Input and Output: ** none ** ** Output: ** none ** ** Return values: ** 0 - success ** -1 - error in computing valid forecast hour ** -2 - error in writing data to database ** -3 - error in converting level ** -4 - error computing forecast day and time ** Remarks: ** This routine takes in the GRIB-2 filename, a pointer (byte offset) ** to the grid within the GRIB file, a pointer to an 'Identification ** Section' data structure, and a pointer to a McIDAS-style GRID header ** data structure. It then uses this information to ** decode the necessary data to fill a new record in the GRIB ** database. ** ** Categories: ** none */ int McMySQLPutGrib2(char *grib_file_name, long int ptr_to_grid, long int grid_size, int levelType, g2int *indSection, g2int *idSection, Fint *GridNav, gribfield *grb2fld) { char *query; char *field_list; char *value_list; char *temp_str; int geo_ID = 0; int param_ID = 0; int year = 0; int runtime = 0; int forecast_day = 0; int forecast_time = 0; int j_day = 0; int param_scale = 0; int level_scale = 0; int ok = 0; int i; int type_mask; int time_ave_diff; int lev_ave_diff=0; int period_1; int period_2; int fcst_unit; int time_range; char param_short[5]; char param_long[49]; char param_units[5]; char level[80]; char level_value[5]; char level_units[5]; char proj_short[5]; char proj_long[37]; char ensemble[5]; char model_name[5]; char *tempEnsemble; FILE *handle; char file_name[L_SIZE]; /* file output name */ char file_temp[L_SIZE]; /* file output name */ const char *f_ptr; MYSQL grib_database; MCGRIDHEADER mcgridheader; /* * Now we need to get the information from the GRIB message that we will * be inserting into the GRIB database. */ /*--- geo_ID not available in GRIB-2 --------------------------------------------------- */ /*--- Get parameter ID ---------------------------------------------------- */ param_ID = grb2fld->ipdtmpl[10]; /*--- Get julian date ----------------------------------------------------- */ ok = Mcdmytocyd (idSection[7], idSection[6], idSection[5], &j_day); if (ok < 0) Mceprintf("Mcdmytocyd returns %i in McMySQLPutGrib2\n",ok); /*--- Get run time -------------------------------------------------------- */ /* put in HHMMSS format to compare in database runtime = idSection[8] * 100 + idSection[9];*/ runtime = idSection[8] * 10000 + idSection[9]*100 + idSection[10]; /*--- Get time and/or level differencing and/or averaging information ----- */ /*--- Initialize mcgridheader.type_mask ---*/ level_scale=GridNav[10]; type_mask=GridNav[12]; time_ave_diff=GridNav[13]; lev_ave_diff=GridNav[14]; period_1=0; period_2=0; /*--- Get forecast hour, day, and time ------------------------------------ */ ok = GetForecastDayTime( j_day, runtime, GridNav[5], &forecast_day, &forecast_time ); if ( ok < 0 ) { Mcprintf("McMySQLPut GetForecastDayTime ok=%i\n",ok); Mcprintf("day,month,year,century,cyear,j_day: %i,%i,%i,%i\n", idSection[7],idSection[6],idSection[5],j_day); Mcprintf("model_name: %s\n",(char *)&GridNav[32]); return (-4); } /*--- Get the parameter information --------------------------------------- */ memcpy(param_short,(char *)&GridNav[6],4); param_short[4]='\0'; memcpy(param_long,(char *)&GridNav[52],48); param_long[48]='\0'; memcpy(param_units,(char *)&GridNav[8],4); param_units[4]='\0'; memcpy(ensemble,(char *)&GridNav[19],4); ensemble[4]='\0'; memcpy(model_name,(char *)&GridNav[32],4); model_name[4]='\0'; tempEnsemble = calloc((size_t)L_PARM,sizeof(char)); /* Update long parameter if this is an ensemble */ if (strncmp(ensemble,"+0",2)==0) { sprintf(tempEnsemble," High-Res Ens Control"); (void) strncat((char*) &(param_long),tempEnsemble,strlen(tempEnsemble)); } else if (strncmp(ensemble,"-0",2)==0) { sprintf(tempEnsemble," Low-Res Ens Control"); (void) strncat((char*) &(param_long),tempEnsemble,strlen(tempEnsemble)); } else if (strncmp(ensemble,"+",1)==0 || strncmp(ensemble,"-",1)==0) { sprintf(tempEnsemble," Ens Perturbation"); (void) strncat((char*) &(param_long),tempEnsemble,strlen(tempEnsemble)); } free(tempEnsemble); param_long[47]='\0'; /* Convert the level into a McIDAS level string */ ok = GridLevel2Str(GridNav[9], levelType, level); /* Put the level units into a string */ (void) memmove(level_units, (char*) &GridNav[11], sizeof(char)*4); level_units[4] = '\0'; ok = GetGrib2ProjectionNames( grb2fld->igdtnum, &GridNav[0], proj_short,proj_long); /*--- Build a list of fields and a list of values which will be ------------ */ /* used to generate a MySQL query string */ field_list = calloc((size_t)QUERY_LEN, sizeof(char)); value_list = calloc((size_t)QUERY_LEN, sizeof(char)); temp_str = calloc((size_t)80, sizeof(char)); memset(field_list, 0, (size_t)QUERY_LEN); memset(value_list, 0, (size_t)QUERY_LEN); strcpy(field_list, "grib_type, "); sprintf(value_list, "'%i', ", indSection[1]); strcat(field_list, "gen_proc_ID, "); sprintf(temp_str, "'%i', ", GridNav[49]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "j_day, "); sprintf(temp_str, "'%i', ", j_day); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "runtime, "); sprintf(temp_str, "'%i', ", runtime); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "forecast_hour, "); sprintf(temp_str, "'%i', ", GridNav[5]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "geo_ID, "); sprintf(temp_str, "'%i', ", geo_ID); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "level_ID, "); sprintf(temp_str, "'%i', ", levelType); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "param_ID, "); sprintf(temp_str, "'%i', ", param_ID); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "grib_file_name, "); sprintf(temp_str, "'%s', ", grib_file_name); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "grid_size, "); sprintf(temp_str, "'%i', ", grid_size); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "ptr_to_grid, "); sprintf(temp_str, "'%i', ", ptr_to_grid); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "param_short, "); sprintf(temp_str, "'%s', ", param_short); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "level, "); sprintf(temp_str, "'%s', ", level); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "level_units, "); sprintf(temp_str, "'%s', ", level_units); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "level_scale, "); sprintf(temp_str, "'%i', ", level_scale); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "ensemble, "); sprintf(temp_str, "'%s', ", ensemble); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "model_name, "); sprintf(temp_str, "'%s', ", model_name); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "proj_short, "); sprintf(temp_str, "'%s', ", proj_short); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "type_mask, "); sprintf(temp_str, "'%i', ", type_mask); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "time_ave_diff, "); sprintf(temp_str, "'%i', ", time_ave_diff); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "lev_ave_diff, "); sprintf(temp_str, "'%i', ", lev_ave_diff); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "period_1, "); sprintf(temp_str, "'%i', ", period_1); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "period_2, "); sprintf(temp_str, "'%i', ", period_2); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "grib_version, "); sprintf(temp_str, "'%i', ", indSection[1]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "num_rows, "); sprintf(temp_str, "'%i', ", GridNav[1]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "num_columns, "); sprintf(temp_str, "'%i', ", GridNav[2]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "num_points, "); sprintf(temp_str, "'%i', ", GridNav[0]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "forecast_day, "); sprintf(temp_str, "'%i', ", forecast_day); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "forecast_time, "); sprintf(temp_str, "'%i', ", forecast_time); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "param_long, "); sprintf(temp_str, "'%s', ", param_long); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "proj_long, "); sprintf(temp_str, "'%s', ", proj_long); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "param_scale, "); sprintf(temp_str, "'%i', ", param_scale); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav1, "); sprintf(temp_str, "'%i', ", GridNav[34]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav2, "); sprintf(temp_str, "'%i', ", GridNav[35]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav3, "); sprintf(temp_str, "'%i', ", GridNav[36]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav4, "); sprintf(temp_str, "'%i', ", GridNav[37]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav5, "); sprintf(temp_str, "'%i', ", GridNav[38]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "nav6, "); sprintf(temp_str, "'%i', ", GridNav[39]); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "param_units, "); sprintf(temp_str, "'%s', ", param_units); strncat(value_list, temp_str, strlen(temp_str)); strcat(field_list, "field_number\0"); sprintf(temp_str, "'%i'\0", grb2fld->ifldnum); strncat(value_list, temp_str, strlen(temp_str)); /*--- Create query string for input into database ------------------------- */ query = calloc((size_t)QUERY_LEN, sizeof(char)); sprintf(query, "INSERT INTO file_list (%s) VALUES (%s)", field_list, value_list); /*--- Initialize MySQL object and connect to database --------------------- */ mysql_init(&grib_database); if (!mysql_real_connect(&grib_database,"localhost","gribwrite", "gribwrite","mcrtgrib",0,NULL,0)) { Mcprintf("MySQL: %s\n", mysql_error(&grib_database)); mysql_close(&grib_database); free(query); free(field_list); free(value_list); free(temp_str); return(-2); } /*--- Insert query string into database as a new record ------------------- */ if ( mysql_query(&grib_database, query) != 0 ) { Mcprintf("MySQL: %s\n", mysql_error(&grib_database)); Mcprintf("Query: %s\n", query); Mcprintf("param_short=%s, level=%s, %i\n",param_short,level,level); mysql_close(&grib_database); free(query); free(field_list); free(value_list); free(temp_str); return(-3); } /*--- Close database object, clean up memory, and return ------------------ */ mysql_close(&grib_database); free(query); free(field_list); free(value_list); free(temp_str); return(0); } #endif /***********************************************************/ /* * Mcgrib2tofilename - build the GRIB-2 filename from info in the GRIB-2 Header * * returns * -1 malloc error * -2 could not convert forecast unit to valid time */ static int Mcgrib2tofilename (g2int *idSection, Fint *GridNav, int n_gb2nav, GB2NAVTAB *navList, char **filename, int file_name_format, int n_no_decode,NODECODE* no_dec) { int j_day; int runtime, hhRuntime; int ok,grb2ok; char cmodel[14]; /**filename = malloc (256 * sizeof (char));*/ if (*filename == (char *)NULL){ Mceprintf("Returning -1 from Mcgrib2tofilename\n"); return (-1); } runtime = idSection[8] * 100 + idSection[9]; hhRuntime = idSection[8] + idSection[9]; ok = Mcdmytocyd (idSection[7], idSection[6], idSection[5], &j_day); if (ok < 0) Mceprintf("Mcdmytocyd returns %i in Mcgrib2tofilename\n",ok); grb2ok=grb2Lookup(n_gb2nav,navList,GridNav,cmodel); ok = no_decode_grb2(n_no_decode,no_dec,cmodel,hhRuntime,GridNav[5]); if (ok != 0) return(-20); /* * Set the GRIB file name format: if TITLEFLAG is set to 3 * in the config file then prepend the text model name to * the GRIB file name. */ if ( file_name_format == 3 ) { /* To properly extract the model name, we have to do this!*/ if (grb2ok < 0) ok=Mcgtpstrg((char*)&GridNav[32],1,"",(char *) &cmodel); sprintf (*filename, "%s.%d.%d.%d.%d.grb2", cmodel, GridNav[49], j_day, runtime, GridNav[5]); } else { sprintf (*filename, "%d.%d.%d.%d.%d.grb2", GridNav[49], j_day, runtime, GridNav[5]); } return (0); } /*********************************************************** ** Name: ** GetGrib2ProjectionNames - Get a projection string ** for a GRIB-2 file based on grid definition section ** template number ** ** ** Interface: ** int ** GetGrib2ProjectionNames (int templateNum, char proj_short[5], char proj_long[37]) ** ** Input: ** templateNum - Template number for a grid definition section in a GRIB-2 file ** ** Input and Output: ** none ** ** Output: ** proj_short - null-terminated string containing the ** abbreviated name of the grid projection ** proj_long - null-terminated string containing the ** long name of the grid projection ** ** Return values: ** 0 - success ** Remarks: ** none ** ** Categories: ** none */ int GetGrib2ProjectionNames( g2int templateNum, Fint* GridNav, char proj_short[5],char proj_long[37]) { int ok; switch (templateNum) { case 0: ok=Mcgtpstrg("MERC",1,"",proj_short); ok=Mcgtpstrg("Equidistant_Cylindrical",1,"",proj_long); break; case 1: ok=Mcgtpstrg("MERC",1,"",proj_short); ok=Mcgtpstrg("Equidistant_Cylindrical_Rotated",1,"",proj_long); break; case 2: ok=Mcgtpstrg("MERC",1,"",proj_short); ok=Mcgtpstrg("Equidistant_Cylindrical_Stretched",1,"",proj_long); break; case 3: ok=Mcgtpstrg("MERC",1,"",proj_short); ok=Mcgtpstrg("Equi_Cylindrical_Rotated_Stretched",1,"",proj_long); break; case 10: ok=Mcgtpstrg("MERC",1,"",proj_short); ok=Mcgtpstrg("Mercator",1,"",proj_long); break; case 20: ok=Mcgtpstrg("PS",1,"",proj_short); ok=Mcgtpstrg("Polar_Stereographic",1,"",proj_long); break; case 30: ok=Mcgtpstrg("LAMB",1,"",proj_short); /* If Latin 1 == Latin 2, then the projection is a tangent cone */ if (GridNav[38]==GridNav[39]) ok=Mcgtpstrg("Lambert_Conformal_Tangent_Cone",1,"",proj_long); else ok=Mcgtpstrg("Lambert_Conformal_Secant",1,"",proj_long); break; case 40: ok=Mcgtpstrg("GAUS",1,"",proj_short); ok=Mcgtpstrg("Gaussian",1,"",proj_long); break; case 41: ok=Mcgtpstrg("GAUS",1,"",proj_short); ok=Mcgtpstrg("Gaussian_Rotated",1,"",proj_long); break; case 42: ok=Mcgtpstrg("GAUS",1,"",proj_short); ok=Mcgtpstrg("Gaussian_Stretched",1,"",proj_long); break; case 43: ok=Mcgtpstrg("GAUS",1,"",proj_short); ok=Mcgtpstrg("Gaussian_Rotated_Stretched",1,"",proj_long); break; default: ok=Mcgtpstrg("UNKN",1,"",proj_short); ok=Mcgtpstrg("Unknown_Projection",1,"",proj_long); break; } return (0); } /********************************************************** ** Name: ** getModelStr - Convert integer Model Name to character string ** ** Interface: ** int getModelStr(int ModelName, charModelName[] ) ** ** Input: ** ModelName - integer representation of model name, taken from grid header ** ** Input and Output: ** none ** ** Output: ** charModelName - character representation of grid model name ** ** Return values: ** 0 - success ** -1 - invalid level ** -2 - clev is too short to accept string ** ** Remarks: ** The function returns the character representation of the model name ** ** Categories: ** grid ** utility */ int getModelStr (int intModel, char* charModel) { /* Model Name should be a 4-character all uppercase letters */ char ctemp[6]; int i; int charCount=0; int alphaCount=0; int leadingWSCount=0; /* count leading white space */ (void) memcpy(ctemp,&intModel,sizeof(ctemp)); /*look for the first non-space non alphabetic character and make that the termination position*/ for (i=0; i 0) { for (i=leadingWSCount; i< sizeof(ctemp); i++) ctemp[i-leadingWSCount]=ctemp[i]; charCount -= leadingWSCount; } (void) memmove(charModel, ctemp, sizeof(ctemp)); charModel[alphaCount] = '\0'; /* strings of model names are currently not any longer than 4 characters */ if (charCount > 0) charModel[4] = '\0'; return (0); } /********************** End of File ********************/