/* Name- processGRAS.c Language- C Type- MAIN Version- 1.0 Date- 4/12/2017 Programmer- Mike Pettey (IMSG) Function- This program extracts data from P72 EDR files in HDF5 format and writes the data to an EDGE orbital file. The selected data is defined in the run script. Also in the run script are the starting date (YYYYMMDD) and hour and the ending date and hour. */ #include #include #include #include #include #include #include "nprovs_to_netcdf.h" #define ERR(e) {printf("Error: %s, error num = %d\n", nc_strerror(e),e);} #define NDIMS 1 int defineVariable(int nc_group_id, char *var_name, nc_type var_type, int ndims, int *dimids, char *attr_string, char *attr); void writeVariableFloat(int group_id, int var_id, size_t *index, size_t *num_vals, float value); void writeVariableShort(int group_id, int var_id, size_t *index, size_t *num_vals, short value); void writeVariableInteger(int group_id, int var_id, size_t *index, size_t *num_vals, long value); void writeArrayFloat(int group_id, int var_id, size_t *index, size_t *num_vals, float *value); void writeVariableByte(int group_id, int var_id, size_t *index, size_t *num_vals, char value); void writeAttributeShort(int grp, char *attrVariable, short attrValue); void writeAttributeText(int grp, char *attrVariable, char *attrValue); void processGRAS(int date_to_process, struct file_data *files, struct platform *platform_ptr, int num_collocations, int platform_index, int data_type, int nc_date_group) { int n, i, date_type, recnum, collocation_num, retval; int nc_group_id, collocation_group_id; size_t num_colls, index[1], num_vals[1], index_2D[2], num_vals_2D[2]; float missing_float, latitude, longitude, level_values[137], raw_data[250]; float pressure, last_pressure, scaling_factor; int year, month, day, hour, minute, second; long offset, yyyymmdd, hhmmss; char col_dir_name[50]; char string4[8], string14[15], string20[21], string32[33]; char *string[1]; short *buffer; int col_scalar_dim; int scalar_dim, dim_levels, dim_raw; int dimid_scalar[1], col_dimid_scalar[1]; int dimid_levels[2], dimid_raw[2]; int col_vid_lat, col_vid_lon, col_vid_date, col_vid_time; int vid_lat, vid_lon, vid_date, vid_time; int vid_gnss_satid, vid_leo_satid, vid_ground_id, vid_occ_id, vid_proc_center; int vid_qc, vid_numlevels, vid_press, vid_press_err, vid_height, vid_height_err; int vid_temp, vid_temp_err, vid_relhum, vid_relhum_err, vid_wvmr, vid_level_qc; int vid_surf_height, vid_surf_press, vid_surf_press_err, vid_surf_qc; int vid_back_source, vid_back_date, vid_back_time, vid_back_per; int vid_numback, vid_back_press, vid_back_press_err, vid_back_height, vid_back_height_err; int vid_back_temp, vid_back_temp_err, vid_back_relhum, vid_back_relhum_err; int vid_back_wvmr, vid_back_surf_height, vid_back_surf_press, vid_back_surf_press_err; int vid_back_surf_qc, vid_numraw, vid_raw_press, vid_raw_lat, vid_raw_lon; int vid_dry_temp, vid_dry_temp_err, vid_dry_temp_qc, vid_raw_height; int vid_dry_refract, vid_dry_refract_err, vid_dry_refract_qc; int vid_pcd_wet, vid_pcd_background, vid_pcd_atm; FILE *in; num_colls = (size_t)num_collocations; missing_float = -32768.0; // If this is the baseline platform, then create another subgroup // for the collocation information if (platform_index == 0) { sprintf(col_dir_name, "Collocation_Info"); if ((retval = nc_def_grp(nc_date_group, col_dir_name, &collocation_group_id))) { if (retval != -42) ERR(retval); } writeAttributeShort(collocation_group_id, "Baseline_Data_Type", platform_ptr->type); writeAttributeText(collocation_group_id, "Baseline_Platform", platform_ptr->description); writeAttributeShort(collocation_group_id, "Baseline_Platform_ID", platform_ptr->id); } // Create a subgroup for this system platform if ((retval = nc_def_grp(nc_date_group, platform_ptr->dir_name, &nc_group_id))) { //if (retval != -42) ERR(retval); } // Set the platform type attribute to the data group type writeAttributeText(nc_group_id, "Platform_Name", platform_ptr->description); // clean_description? writeAttributeShort(nc_group_id, "Platform_ID", platform_ptr->id); writeAttributeShort(nc_group_id, "Platform_Type", platform_ptr->type); writeAttributeText(nc_group_id, "Platform_Data_Source", "GRAS"); //writeAttributeText(nc_group_id, "Platform_NPROVS_Source_Name", nprovs_name); writeAttributeText(nc_group_id, "Platform_NPROVS_Source_Name", platform_ptr->description); // clean_description? // Define the dimensions if ((retval = nc_def_dim(nc_group_id, "Num_Collocations", num_colls, &scalar_dim))) ERR(retval); dimid_scalar[0] = scalar_dim; if ((retval = nc_def_dim(nc_group_id, "Levels", 137, &dim_levels))) ERR(retval); dimid_levels[0] = scalar_dim; dimid_levels[1] = dim_levels; if ((retval = nc_def_dim(nc_group_id, "Raw_Levels", 250, &dim_raw))) ERR(retval); dimid_raw[0] = scalar_dim; dimid_raw[1] = dim_raw; if (platform_index == 0) { if ((retval = nc_def_dim(collocation_group_id, "Num_Collocations", num_colls, &col_scalar_dim))) ERR(retval); col_dimid_scalar[0] = col_scalar_dim; } // Define the variables if (platform_index == 0) { col_vid_lat = defineVariable(collocation_group_id, "latitude", NC_FLOAT, 1, col_dimid_scalar, "units", "degrees_north"); col_vid_lon = defineVariable(collocation_group_id, "longitude", NC_FLOAT, 1, col_dimid_scalar, "units", "degrees_east"); col_vid_date = defineVariable(collocation_group_id, "date", NC_INT, 1, col_dimid_scalar, "format", "yyyymmdd"); col_vid_time = defineVariable(collocation_group_id, "time", NC_INT, 1, col_dimid_scalar, "format", "hhmmss"); } vid_lat = defineVariable(nc_group_id, "latitude", NC_FLOAT, 1, dimid_scalar, "units", "degrees_north"); vid_lon = defineVariable(nc_group_id, "longitude", NC_FLOAT, 1, dimid_scalar, "units", "degrees_east"); vid_date = defineVariable(nc_group_id, "date", NC_INT, 1, dimid_scalar, "format", "yyyymmdd"); vid_time = defineVariable(nc_group_id, "time", NC_INT, 1, dimid_scalar, "format", "hhmmss"); vid_gnss_satid = defineVariable(nc_group_id, "gnss_satellite_id", NC_STRING, 1, dimid_scalar, "string_length", "8"); vid_leo_satid = defineVariable(nc_group_id, "leo_satellite_id", NC_STRING, 1, dimid_scalar, "string_length", "8"); vid_ground_id = defineVariable(nc_group_id, "ground_station_id", NC_STRING, 1, dimid_scalar, "string_length", "8"); vid_occ_id = defineVariable(nc_group_id, "occultation_id", NC_STRING, 1, dimid_scalar, "string_length", "33"); vid_proc_center = defineVariable(nc_group_id, "processing_center", NC_STRING, 1, dimid_scalar, "string_length", "15"); vid_qc = defineVariable(nc_group_id, "overall_quality_value", NC_FLOAT, 1, dimid_scalar, "units", "percent"); vid_numlevels = defineVariable(nc_group_id, "number_of_derived_product_levels", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_press = defineVariable(nc_group_id, "pressure", NC_FLOAT, 2, dimid_levels, "units", "hPa"); vid_press_err = defineVariable(nc_group_id, "pressure_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "hPa"); vid_height = defineVariable(nc_group_id, "geopotential_height", NC_FLOAT, 2, dimid_levels, "units", "km"); vid_height_err = defineVariable(nc_group_id, "geopotential_height_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "m"); vid_temp = defineVariable(nc_group_id, "temperature", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_temp_err = defineVariable(nc_group_id, "temperature_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_relhum = defineVariable(nc_group_id, "specific_humidity", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_relhum_err = defineVariable(nc_group_id, "specific_humidity_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_wvmr = defineVariable(nc_group_id, "calculated_water_vapor_mixing_ratio", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_level_qc = defineVariable(nc_group_id, "product_level_quality", NC_FLOAT, 2, dimid_levels, "units", "percent"); vid_surf_height = defineVariable(nc_group_id, "surface_geopotential_height", NC_FLOAT, 1, dimid_scalar, "units", "meters"); vid_surf_press = defineVariable(nc_group_id, "surface_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_surf_press_err = defineVariable(nc_group_id, "surface_pressure_error_estimate", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_surf_qc = defineVariable(nc_group_id, "surface_pressure_quality_value", NC_FLOAT, 1, dimid_scalar, "units", "percent"); vid_back_source = defineVariable(nc_group_id, "background_source", NC_STRING, 1, dimid_scalar, "string_length", "21"); vid_back_date = defineVariable(nc_group_id, "background_date", NC_INT, 1, dimid_scalar, "format", "yyyymmdd"); vid_back_time = defineVariable(nc_group_id, "background_time", NC_SHORT, 1, dimid_scalar, "format", "hhmm"); vid_back_per = defineVariable(nc_group_id, "forecast_period", NC_BYTE, 1, dimid_scalar, "units", "hour"); vid_numback = defineVariable(nc_group_id, "number_of_background_levels", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_back_press = defineVariable(nc_group_id, "background_pressure", NC_FLOAT, 2, dimid_levels, "units", "hPa"); vid_back_press_err = defineVariable(nc_group_id, "background_pressure_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "hPa"); vid_back_height = defineVariable(nc_group_id, "background_geopotential_height", NC_FLOAT, 2, dimid_levels, "units", "km"); vid_back_height_err = defineVariable(nc_group_id, "background_geopotential_height_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "m"); vid_back_temp = defineVariable(nc_group_id, "background_temperature", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_back_temp_err = defineVariable(nc_group_id, "background_temperature_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_back_relhum = defineVariable(nc_group_id, "background_specific_humidity", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_back_relhum_err = defineVariable(nc_group_id, "background_specific_humidity_error_estimate", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_back_wvmr = defineVariable(nc_group_id, "background_calculated_mixing_ratio", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_back_surf_height = defineVariable(nc_group_id, "background_surface_geopotential_height", NC_FLOAT, 1, dimid_scalar, "units", "meters"); vid_back_surf_press = defineVariable(nc_group_id, "background_surface_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_back_surf_press_err = defineVariable(nc_group_id, "background_surface_pressure_error_estimate", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_back_surf_qc = defineVariable(nc_group_id, "background_surface_pressure_quality_value", NC_FLOAT, 1, dimid_scalar, "units", "percent"); vid_numraw = defineVariable(nc_group_id, "number_of_raw_levels", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_raw_press = defineVariable(nc_group_id, "calculated_raw_pressure", NC_FLOAT, 2, dimid_raw, "units", "hPa"); vid_raw_lat = defineVariable(nc_group_id, "dry_temperature_latitude", NC_FLOAT, 2, dimid_raw, "units", "degrees_north"); vid_raw_lon = defineVariable(nc_group_id, "dry_temperature_longitude", NC_FLOAT, 2, dimid_raw, "units", "degrees_east"); vid_dry_temp = defineVariable(nc_group_id, "raw_dry_temperature", NC_FLOAT, 2, dimid_raw, "units", "K"); vid_dry_temp_err = defineVariable(nc_group_id, "dry_temperature_error_estimate", NC_FLOAT, 2, dimid_raw, "units", "K"); vid_dry_temp_qc = defineVariable(nc_group_id, "dry_temperature_qc", NC_FLOAT, 2, dimid_raw, "units", "percent"); vid_raw_height = defineVariable(nc_group_id, "raw_geometric_height", NC_FLOAT, 2, dimid_raw, "units", "km"); vid_dry_refract = defineVariable(nc_group_id, "raw_refractivity", NC_FLOAT, 2, dimid_raw, "units", "K"); vid_dry_refract_err = defineVariable(nc_group_id, "raw_refractivity_error_estimate", NC_FLOAT, 2, dimid_raw, "units", "K"); vid_dry_refract_qc = defineVariable(nc_group_id, "raw_refractivity_qc", NC_FLOAT, 2, dimid_raw, "units", "percent"); vid_pcd_wet = defineVariable(nc_group_id, "wet_profile_pcd", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_pcd_background = defineVariable(nc_group_id, "background_profile_pcd", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_pcd_atm = defineVariable(nc_group_id, "atm_profile_pcd", NC_SHORT, 1, dimid_scalar, NULL, NULL); // Allocate the memory used by the data buffer buffer = (short *)malloc(platform_ptr->length); collocation_num = -1; // Loop through each record in all of the files and read the data for // this data group into the buffer for (date_type=0; date_type<3; date_type++) { if (date_type == 0) { if ((in=fopen("prev_day.file", "r")) == NULL) { printf("\n\nThe previous day file could not be opened for input.\n"); printf("It will be skipped.\n\n"); in = NULL; } } else if (date_type == 1) { if ((in=fopen("in.file", "r")) == NULL) { printf("\n\nThe input file could not be opened for input.\n"); printf("It will be skipped.\n\n"); in = NULL; } } else { if ((in=fopen("next_day.file", "r")) == NULL) { printf("\n\nThe next day file could not be opened for input.\n"); printf("It will be skipped.\n\n"); in = NULL; } } for (recnum=0; recnumoffset; fseek(in, offset, SEEK_SET); fread(buffer, platform_ptr->length, 1, in); // Process this record if it matches the date to process if (files[date_type].use_record[recnum] == TRUE) { collocation_num++; // Index and num_vals are used to save a single value within the // variable array index[0] = collocation_num; num_vals[0] = 1; // Latitude and longitude if (buffer[3] != -32768) latitude = buffer[3] / 128.0; else latitude = -32768.0; if (buffer[4] != -32768) longitude = buffer[4] / 128.0; else longitude = -32768.0; writeVariableFloat(nc_group_id, vid_lat, index, num_vals, latitude); writeVariableFloat(nc_group_id, vid_lon, index, num_vals, longitude); // Date and time if ((buffer[5] != -32768) && (buffer[6] != -32768) && (buffer[7] != -32768) && (buffer[8] != -32768)) { year = buffer[5]; month = buffer[6] / 100; day = buffer[6] % 100; hour = buffer[7]; minute = buffer[8] / 100; second = buffer[8] % 100; yyyymmdd = (year * 10000) + (month * 100) + day; hhmmss = (hour * 10000) + (minute * 100) + second; } else { yyyymmdd = -32768; hhmmss = -32768; } writeVariableInteger(nc_group_id, vid_date, index, num_vals, yyyymmdd); writeVariableInteger(nc_group_id, vid_time, index, num_vals, hhmmss); // If this is the baseline system, save the collocation information if (platform_index == 0) { writeVariableFloat(collocation_group_id, col_vid_lat, index, num_vals, latitude); writeVariableFloat(collocation_group_id, col_vid_lon, index, num_vals, longitude); writeVariableInteger(collocation_group_id, col_vid_date, index, num_vals, yyyymmdd); writeVariableInteger(collocation_group_id, col_vid_time, index, num_vals, hhmmss); } // Start saving the parameters starting with the GNSS satellite id if ((buffer[10] == -32768) || (buffer[11] == -32768)) { string4[0] = ' '; string4[1] = ' '; string4[2] = ' '; string4[3] = ' '; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } else { string4[0] = (buffer[10] >> 8) & 0xFF; string4[1] = buffer[10] & 0xFF; string4[2] = (buffer[11] >> 8) & 0xFF; string4[3] = buffer[11] & 0xFF; //string4[4] = '\0'; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } string[0] = string4; if (retval = nc_put_vara_string(nc_group_id, vid_gnss_satid, index, num_vals, (const char **)string)) ERR(retval); // LEO satellite id if ((buffer[12] == -32768) || (buffer[13] == -32768)) { string4[0] = ' '; string4[1] = ' '; string4[2] = ' '; string4[3] = ' '; //string4[4] = '\0'; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } else { string4[0] = (buffer[12] >> 8) & 0xFF; string4[1] = buffer[12] & 0xFF; string4[2] = (buffer[13] >> 8) & 0xFF; string4[3] = buffer[13] & 0xFF; //string4[4] = '\0'; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } string[0] = string4; if (retval = nc_put_vara_string(nc_group_id, vid_leo_satid, index, num_vals, (const char **)string)) ERR(retval); // Ground station ID if ((buffer[14] == -32768) || (buffer[15] == -32768)) { string4[0] = ' '; string4[1] = ' '; string4[2] = ' '; string4[3] = ' '; //string4[4] = '\0'; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } else { string4[0] = (buffer[14] >> 8) & 0xFF; string4[1] = buffer[14] & 0xFF; string4[2] = (buffer[15] >> 8) & 0xFF; string4[3] = buffer[15] & 0xFF; //string4[4] = '\0'; string4[4] = ' '; string4[5] = ' '; string4[6] = ' '; string4[7] = ' '; string4[8] = '\0'; } string[0] = string4; if (retval = nc_put_vara_string(nc_group_id, vid_ground_id, index, num_vals, (const char **)string)) ERR(retval); // Occultation ID if ((buffer[16] == -32768) || (buffer[17] == -32768) || (buffer[18] == -32768) || (buffer[19] == -32768) || (buffer[20] == -32768) || (buffer[21] == -32768) || (buffer[22] == -32768) || (buffer[23] == -32768) || (buffer[24] == -32768) || (buffer[25] == -32768) || (buffer[26] == -32768) || (buffer[27] == -32768) || (buffer[28] == -32768) || (buffer[29] == -32768) || (buffer[30] == -32768) || (buffer[31] == -32768)) { for (i=0; i<32; i++) string32[i] = ' '; string32[32] = '\0'; } else { for (i=0; i<16; i++) { string32[i*2] = (buffer[16+i] >> 8) & 0xFF; string32[(i*2)+1] = buffer[16+i] & 0xFF; } string32[32] = '\0'; } string[0] = string32; if (retval = nc_put_vara_string(nc_group_id, vid_occ_id, index, num_vals, (const char **)string)) ERR(retval); // Processing center if ((buffer[32] == -32768) || (buffer[33] == -32768) || (buffer[34] == -32768) || (buffer[35] == -32768) || (buffer[36] == -32768) || (buffer[37] == -32768) || (buffer[38] == -32768)) { for (i=0; i<14; i++) string14[i] = ' '; string14[14] = '\0'; } else { for (i=0; i<7; i++) { string14[i*2] = (buffer[32+i] >> 8) & 0xFF; string14[(i*2)+1] = buffer[32+i] & 0xFF; } string14[14] = '\0'; } string[0] = string14; if (retval = nc_put_vara_string(nc_group_id, vid_proc_center, index, num_vals, (const char **)string)) ERR(retval); // Overall QC if (buffer[39] != -32768) writeVariableFloat(nc_group_id, vid_qc, index, num_vals, (buffer[39]/10.0)); else writeVariableFloat(nc_group_id, vid_qc, index, num_vals, -32768.0); // Derived product levels index_2D[0] = collocation_num; index_2D[1] = 0; num_vals_2D[0] = 1; num_vals_2D[1] = 137; writeVariableShort(nc_group_id, vid_numlevels, index, num_vals, buffer[40]); // Pressures for (n=0; n<137; n++) { if (buffer[589+n] == -32768) level_values[136-n] = -32768.0; else if (n < 80) level_values[136-n] = buffer[589+n] / 10.0; else level_values[136-n] = buffer[589+n] / 100.0; } writeArrayFloat(nc_group_id, vid_press, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[726+n] != -32768) level_values[136-n] = buffer[726+n] / 1000.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_press_err, index_2D, num_vals_2D, level_values); // Geopotential height for (n=0; n<137; n++) { if (buffer[41+n] != -32768) level_values[136-n] = buffer[41+n] / 100.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_height, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[178+n] != -32768) level_values[136-n] = buffer[178+n] / 100.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_height_err, index_2D, num_vals_2D, level_values); // Temperature for (n=0; n<137; n++) { if (buffer[315+n] != -32768) level_values[136-n] = buffer[315+n] / 64.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_temp, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[452+n] != -32768) level_values[136-n] = buffer[452+n] / 64.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_temp_err, index_2D, num_vals_2D, level_values); // Humidity and mixing ratio for (n=0; n<137; n++) { if (buffer[863+n] != -32768) level_values[136-n] = (float)(exp(buffer[863+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_relhum, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[1000+n] != -32768) level_values[136-n] = (float)(exp(buffer[1000+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_relhum_err, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[1137+n] != -32768) level_values[136-n] = (float)(exp(buffer[1137+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_wvmr, index_2D, num_vals_2D, level_values); // Level QC for (n=0; n<137; n++) { if (buffer[1274+n] != -32768) level_values[136-n] = buffer[1274+n] / 10.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_level_qc, index_2D, num_vals_2D, level_values); // Surface values if (buffer[1411] != -32768) writeVariableFloat(nc_group_id, vid_surf_height, index, num_vals, (buffer[1411]/10.0)); else writeVariableFloat(nc_group_id, vid_surf_height, index, num_vals, -32768.0); if (buffer[1412] != -32768) writeVariableFloat(nc_group_id, vid_surf_press, index, num_vals, (buffer[1412]/10.0)); else writeVariableFloat(nc_group_id, vid_surf_press, index, num_vals, -32768.0); if (buffer[1413] != -32768) writeVariableFloat(nc_group_id, vid_surf_press_err, index, num_vals, (buffer[1413]/100.0)); else writeVariableFloat(nc_group_id, vid_surf_press_err, index, num_vals, -32768.0); if (buffer[1414] != -32768) writeVariableFloat(nc_group_id, vid_surf_qc, index, num_vals, (buffer[1414]/10.0)); else writeVariableFloat(nc_group_id, vid_surf_qc, index, num_vals, -32768.0); // Background source if ((buffer[1415] == -32768) || (buffer[1416] == -32768) || (buffer[1417] == -32768) || (buffer[1418] == -32768) || (buffer[1419] == -32768) || (buffer[1420] == -32768) || (buffer[1421] == -32768) || (buffer[1422] == -32768) || (buffer[1423] == -32768) || (buffer[1424] == -32768)) { for (i=0; i<20; i++) string20[i] = ' '; string20[20] = '\0'; } else { for (i=0; i<10; i++) { string20[i*2] = (buffer[1415+i] >> 8) & 0xFF; string20[(i*2)+1] = buffer[1415+i] & 0xFF; } string20[20] = '\0'; } string[0] = string20; if (retval = nc_put_vara_string(nc_group_id, vid_back_source, index, num_vals, (const char **)string)) ERR(retval); // Background date and time if ((buffer[1425] != -32768) && (buffer[1426] != -32768)) { yyyymmdd = (buffer[1425] * 10000) + buffer[1426]; writeVariableInteger(nc_group_id, vid_back_date, index, num_vals, yyyymmdd); } else { writeVariableInteger(nc_group_id, vid_back_date, index, num_vals, -32768.0); } writeVariableShort(nc_group_id, vid_back_time, index, num_vals, buffer[1427]); if (buffer[1428] != -32768) writeVariableByte(nc_group_id, vid_back_per, index, num_vals, (char)(buffer[1428]/100)); else writeVariableByte(nc_group_id, vid_back_per, index, num_vals, (char)-128); // Background data writeVariableShort(nc_group_id, vid_numback, index, num_vals, buffer[1429]); // Pressures for (n=0; n<137; n++) { if (buffer[1978+n] == -32768) level_values[136-n] = -32768.0; else if (n < 80) level_values[136-n] = buffer[1978+n] / 10.0; else level_values[136-n] = buffer[1978+n] / 100.0; } writeArrayFloat(nc_group_id, vid_back_press, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[2115+n] != -32768) level_values[136-n] = buffer[2115+n] / 10.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_press_err, index_2D, num_vals_2D, level_values); // Geopotential height for (n=0; n<137; n++) { if (buffer[1430+n] != -32768) level_values[136-n] = buffer[1430+n] / 100.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_height, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[1567+n] != -32768) level_values[136-n] = buffer[1567+n] / 10.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_height_err, index_2D, num_vals_2D, level_values); // Temperature for (n=0; n<137; n++) { if (buffer[1704+n] != -32768) level_values[136-n] = buffer[1704+n] / 64.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_temp, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[1841+n] != -32768) level_values[136-n] = buffer[1841+n] / 64.0; else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_temp_err, index_2D, num_vals_2D, level_values); // Humidity and mixing ratio for (n=0; n<137; n++) { if (buffer[2252+n] != -32768) level_values[136-n] = (float)(exp(buffer[2252+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_relhum, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[2389+n] != -32768) level_values[136-n] = (float)(exp(buffer[2389+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_relhum_err, index_2D, num_vals_2D, level_values); for (n=0; n<137; n++) { if (buffer[2526+n] != -32768) level_values[136-n] = (float)(exp(buffer[2526+n]/1024.0)); else level_values[136-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_back_wvmr, index_2D, num_vals_2D, level_values); // Background surface values if (buffer[2663] != -32768) writeVariableFloat(nc_group_id, vid_back_surf_height, index, num_vals, (buffer[2663]/10.0)); else writeVariableFloat(nc_group_id, vid_back_surf_height, index, num_vals, -32768.0); if (buffer[2664] != -32768) writeVariableFloat(nc_group_id, vid_back_surf_press, index, num_vals, (buffer[2664]/10.0)); else writeVariableFloat(nc_group_id, vid_back_surf_press, index, num_vals, -32768.0); if (buffer[2665] != -32768) writeVariableFloat(nc_group_id, vid_back_surf_press_err, index, num_vals, (buffer[2665]/100.0)); else writeVariableFloat(nc_group_id, vid_back_surf_press_err, index, num_vals, -32768.0); if (buffer[2666] != -32768) writeVariableFloat(nc_group_id, vid_back_surf_qc, index, num_vals, (buffer[2666]/10.0)); else writeVariableFloat(nc_group_id, vid_back_surf_qc, index, num_vals, -32768.0); // PCD qc values if (buffer[5168] != -32768) writeVariableShort(nc_group_id, vid_pcd_wet, index, num_vals, buffer[5168]); else writeVariableShort(nc_group_id, vid_pcd_wet, index, num_vals, -32768.0); if (buffer[5169] != -32768) writeVariableShort(nc_group_id, vid_pcd_background, index, num_vals, buffer[5169]); else writeVariableShort(nc_group_id, vid_pcd_background, index, num_vals, -32768.0); if (buffer[5170] != -32768) writeVariableShort(nc_group_id, vid_pcd_atm, index, num_vals, buffer[5170]); else writeVariableShort(nc_group_id, vid_pcd_atm, index, num_vals, -32768.0); // Raw product levels index_2D[0] = collocation_num; index_2D[1] = 0; num_vals_2D[0] = 1; num_vals_2D[1] = 250; writeVariableShort(nc_group_id, vid_numraw, index, num_vals, buffer[2667]); // Raw pressures last_pressure = 10000.0; scaling_factor = 10.0; for (n=0; n<250; n++) { if (buffer[4418+n] == -32768) { raw_data[249-n] = -32768.0; } else { pressure = buffer[4418+n] / scaling_factor; if (pressure <= last_pressure) { raw_data[249-n] = pressure; last_pressure = pressure; } else { while ((pressure > last_pressure) && (scaling_factor < 10000)) { scaling_factor = scaling_factor * 10.0; pressure = buffer[4418+n] / scaling_factor; } raw_data[249-n] = pressure; last_pressure = pressure; } //printf("RAWPRESS %d %d %f %f\n", n, buffer[4418+n], pressure, scaling_factor); } } writeArrayFloat(nc_group_id, vid_raw_press, index_2D, num_vals_2D, raw_data); // Raw latitude and longitude for (n=0; n<250; n++) { if (buffer[4668+n] != -32768) raw_data[249-n] = buffer[4668+n] / 128.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_raw_lat, index_2D, num_vals_2D, raw_data); for (n=0; n<250; n++) { if (buffer[4918+n] != -32768) raw_data[249-n] = buffer[4918+n] / 128.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_raw_lon, index_2D, num_vals_2D, raw_data); // Dry temperature for (n=0; n<250; n++) { if (buffer[3668+n] != -32768) raw_data[249-n] = buffer[3668+n] / 64.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_temp, index_2D, num_vals_2D, raw_data); for (n=0; n<250; n++) { if (buffer[3918+n] != -32768) raw_data[249-n] = buffer[3918+n] / 64.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_temp_err, index_2D, num_vals_2D, raw_data); for (n=0; n<250; n++) { if (buffer[4168+n] != -32768) raw_data[249-n] = buffer[4168+n] / 10.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_temp_qc, index_2D, num_vals_2D, raw_data); // Geometric height for (n=0; n<250; n++) { if (buffer[2668+n] != -32768) raw_data[249-n] = buffer[2668+n] / 100.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_raw_height, index_2D, num_vals_2D, raw_data); // Raw refactivity for (n=0; n<250; n++) { if (buffer[2918+n] != -32768) raw_data[249-n] = (float)(exp(buffer[2918+n]/1024.0)); else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_refract, index_2D, num_vals_2D, raw_data); for (n=0; n<250; n++) { if (buffer[3168+n] != -32768) raw_data[249-n] = buffer[3168+n] / 10.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_refract_err, index_2D, num_vals_2D, raw_data); for (n=0; n<250; n++) { if (buffer[3418+n] != -32768) raw_data[249-n] = buffer[3418+n] / 10.0; else raw_data[249-n] = -32768.0; } writeArrayFloat(nc_group_id, vid_dry_refract_qc, index_2D, num_vals_2D, raw_data); } // if (yyyymmdd == date_to_process... } // for (recnum=0... if (in != NULL) fclose(in); } // for (date_type=0... // Free the memory used by the buffer free(buffer); } // end of file