/* Name- processRaob01.c Language- C Type- MAIN Version- 1.0 Date- 2/02/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" struct merged_data { int std_or_sig; float pressure; float temp; float radcor_temp;; float wvmr; float radcor_wvmr; float background_temp; float background_wvmr; float drift_time; float drift_latitude; float drift_longitude; float wind_dir; float wind_speed; int pressure_qc; int temp_qc; int humidity_qc; int missing_flag; struct merged_data *next; }; #define ERR(e) {printf("Error: %s, error num = %d\n", nc_strerror(e),e);} #define NDIMS 1 #define SIGNIFICANT 0 #define STANDARD 1 #define TRUE 0 #define FALSE 1 float dwptToWvmr(float pressure, float dwpt); int defineVariable(int nc_group_id, char *var_name, nc_type var_type, int ndims, int *dimids, char *attr_string, char *attr); void writeVariableByte(int group_id, int var_id, size_t *index, size_t *num_vals, char value); 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 writeVariableText(int group_id, char *var_name, char *var_value); void writeArrayByte(int group_id, int var_id, size_t *index, size_t *num_vals, char *value); void writeArrayShort(int group_id, int var_id, size_t *index, size_t *num_vals, short *value); void writeArrayFloat(int group_id, int var_id, size_t *index, size_t *num_vals, float *value); void writeAttributeShort(int grp, char *attrVariable, short attrValue); void writeAttributeText(int grp, char *attrVariable, char *attrValue); void processRaob01(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, level, level_inserted; 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, std_level_pressures[18], pressure; float lpw[18], tropo[5], gfs[26]; int year, month, day, hour, minute, second; long offset, yyyymmdd, hhmmss; char col_dir_name[50]; char sonde_id[9]; char *string[1]; short *buffer; char merged_std_sig[118], merged_press_qcs[118], merged_temp_qcs[118]; char merged_humid_qcs[118], merged_height_qcs[118], merged_wind_qcs[118]; char merged_missing_flags[118]; float merged_pressures[118], merged_temps[118], merged_radcor_temps[118]; float merged_cfsr_temps[118], merged_reanal_temps[118], merged_wvmrs[118]; float merged_radcor_wvmrs[118], merged_cfsr_wvmrs[118], merged_reanal_wvmrs[118]; float merged_drift_times[118], merged_drift_lats[118], merged_drift_lons[118]; float merged_heights[118], merged_wind_dirs[118], merged_wind_speeds[118]; float merged_back_temps[118], merged_back_wvmrs[118]; int col_scalar_dim; int scalar_dim, dim_levels, dim_lpw; int dimid_scalar[1], col_dimid_scalar[1]; int dimid_levels[2], dimid_lpw[2]; int col_vid_lat, col_vid_lon, col_vid_date, col_vid_time; int vid_sonde_id, vid_lat, vid_lon, vid_date, vid_time; int vid_elevation, vid_report_type, vid_instrument_type, vid_terrain; int vid_lo_interp_press, vid_hi_interp_press; int vid_qc_flag, vid_nprovs_qc; int vid_vert_ext, vid_superad, vid_inversion, vid_temp_gap; int vid_tpw, vid_lpw, vid_surf_press, vid_surf_temp, vid_surf_wvmr, vid_surf_dwpt; int vid_tropo_press; // int vid_tpw_cat // int vid_inversion_type; int vid_low_wvmr, vid_high_wvmr; int vid_press, vid_temps, vid_radcor_temps, vid_back_temps; int vid_wvmrs, vid_radcor_wvmrs, vid_back_wvmrs; int vid_drift_times, vid_drift_lats, vid_drift_lons; int vid_press_qcs, vid_temp_qcs; int vid_humid_qcs, vid_missing_flags, vid_std_sig_flags; FILE *in; struct merged_data *merged_levels; struct merged_data *new_level; struct merged_data *ptr; struct merged_data *prev_ptr; std_level_pressures[0] = 1000.0; std_level_pressures[1] = 925.0; std_level_pressures[2] = 850.0; std_level_pressures[3] = 700.0; std_level_pressures[4] = 500.0; std_level_pressures[5] = 400.0; std_level_pressures[6] = 300.0; std_level_pressures[7] = 250.0; std_level_pressures[8] = 200.0; std_level_pressures[9] = 150.0; std_level_pressures[10] = 100.0; std_level_pressures[11] = 70.0; std_level_pressures[12] = 50.0; std_level_pressures[13] = 30.0; std_level_pressures[14] = 20.0; std_level_pressures[15] = 10.0; std_level_pressures[16] = 7.0; std_level_pressures[17] = 5.0; num_colls = (size_t)num_collocations; missing_float = -32768.0; // If this is the baseline platform, then create a 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", "Radiosonde Version 1"); //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", 118, &dim_levels))) ERR(retval); if ((retval = nc_def_dim(nc_group_id, "LPW_Layers", 18, &dim_lpw))) ERR(retval); dimid_levels[0] = scalar_dim; dimid_levels[1] = dim_levels; dimid_lpw[0] = scalar_dim; dimid_lpw[1] = dim_lpw; 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_sonde_id = defineVariable(nc_group_id, "sonde_station_id", NC_STRING, 1, dimid_scalar, "string_length", "9"); vid_elevation = defineVariable(nc_group_id, "elevation", NC_INT, 1, dimid_scalar, NULL, NULL); vid_report_type = defineVariable(nc_group_id, "report_type", NC_SHORT, 1, dimid_scalar, NULL, NULL); vid_instrument_type = defineVariable(nc_group_id, "instrument_type", NC_SHORT, 1, dimid_scalar, "source", "NCEP Common Code Table S-2: Radiosonde/Sounding System Used"); vid_terrain = defineVariable(nc_group_id, "terrain", NC_BYTE, 1, dimid_scalar, "values", "0=Island Coast, 1=Mainland Inland, 2=Mainland Coast, 3=Island Inland, 4=Ship"); vid_lo_interp_press = defineVariable(nc_group_id, "lowest_interpolated_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_hi_interp_press = defineVariable(nc_group_id, "highest_interpolated_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_qc_flag = defineVariable(nc_group_id, "sonde_qc", NC_BYTE, 1, dimid_scalar, "values", "0=pass, 1=fail"); vid_nprovs_qc = defineVariable(nc_group_id, "nprovs_qc", NC_BYTE, 1, dimid_scalar, "values", "0=pass, 1=fail"); vid_vert_ext = defineVariable(nc_group_id, "vertical_extent_flag", NC_BYTE, 1, dimid_scalar, "values", "0=greater than 5 km, 1=less than 5 km"); vid_superad = defineVariable(nc_group_id, "profile_superadiabatic", NC_BYTE, 1, dimid_scalar, "values", "0=not superadiabatic, 1=marginal, 2=moderate, 3=severe"); vid_inversion = defineVariable(nc_group_id, "profile_inversion", NC_BYTE, 1, dimid_scalar, "values", "0=no inversion, 1=depth<2.5km, 2=depth>2.5km"); // vid_tpw_cat = defineVariable(nc_group_id, "total_precipitable_water_category", NC_BYTE, 1, dimid_scalar, // "values", "0=tpw < 0 mm, 1=between 0 and 15mm, 2=between 15 and 30mm, 3=between 30 and 45 mm, 4=between 45 and 60mm, 5=greater than 60mm"); // vid_inversion_type = defineVariable(nc_group_id, "inversion_type", NC_BYTE, 1, dimid_scalar, // "values", "0=no inversion, 1=surface inversion"); vid_tropo_press = defineVariable(nc_group_id, "tropopause_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_surf_press = defineVariable(nc_group_id, "surface_pressure", NC_FLOAT, 1, dimid_scalar, "units", "hPa"); vid_surf_temp = defineVariable(nc_group_id, "surface_temperature", NC_FLOAT, 1, dimid_scalar, "units", "K"); vid_surf_wvmr = defineVariable(nc_group_id, "surface_water_vapor_mixing_ratio", NC_FLOAT, 1, dimid_scalar, "units", "g/kg"); vid_surf_dwpt = defineVariable(nc_group_id, "surface_dewpoint_temperature", NC_FLOAT, 1, dimid_scalar, "units", "K"); vid_low_wvmr = defineVariable(nc_group_id, "lowest_level_water_vapor_mixing_ratio", NC_FLOAT, 1, dimid_scalar, "units", "g/kg"); vid_high_wvmr = defineVariable(nc_group_id, "highest_level_water_vapor_mixing_ratio", NC_FLOAT, 1, dimid_scalar, "units", "g/kg"); vid_tpw = defineVariable(nc_group_id, "total_precipitable_water", NC_FLOAT, 1, dimid_scalar, "units", "mm"); vid_lpw = defineVariable(nc_group_id, "layer_precipitable_water", NC_FLOAT, 2, dimid_lpw, "units", "mm"); vid_temp_gap = defineVariable(nc_group_id, "temperature_data_gap_flag", NC_BYTE, 1, dimid_scalar, "values", "0=no gap, 1=gap exists"); // Merged standard and significant level variables vid_std_sig_flags = defineVariable(nc_group_id, "standard_or_significant_level_flag", NC_BYTE, 2, dimid_levels, "values", "0=Significant Level, 1=Standard Level"); vid_press = defineVariable(nc_group_id, "pressure", NC_FLOAT, 2, dimid_levels, "units", "hPa"); vid_temps = defineVariable(nc_group_id, "temperature", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_radcor_temps = defineVariable(nc_group_id, "radiation_corrected_temperature", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_wvmrs = defineVariable(nc_group_id, "water_vapor_mixing_ratio", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_radcor_wvmrs = defineVariable(nc_group_id, "radiation_corrected_water_vapor_mixing_ratio", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_back_temps = defineVariable(nc_group_id, "gfs_forecast_background_temperature", NC_FLOAT, 2, dimid_levels, "units", "K"); vid_back_wvmrs = defineVariable(nc_group_id, "gfs_forecast_background_water_vapor_mixing_ratio", NC_FLOAT, 2, dimid_levels, "units", "g/kg"); vid_drift_times = defineVariable(nc_group_id, "balloon_drift_time_delta", NC_FLOAT, 2, dimid_levels, "units", "hours"); vid_drift_lats = defineVariable(nc_group_id, "balloon_drift_latitude", NC_FLOAT, 2, dimid_levels, "units", "degrees_north"); vid_drift_lons = defineVariable(nc_group_id, "balloon_drift_longitude", NC_FLOAT, 2, dimid_levels, "units", "degrees_east"); vid_press_qcs = defineVariable(nc_group_id, "pressure_qc_flag", NC_BYTE, 2, dimid_levels, NULL, NULL); vid_temp_qcs = defineVariable(nc_group_id, "temperature_qc_flag", NC_BYTE, 2, dimid_levels, NULL, NULL); vid_humid_qcs = defineVariable(nc_group_id, "humidity_qc_flag", NC_BYTE, 2, dimid_levels, NULL, NULL); vid_missing_flags = defineVariable(nc_group_id, "level_missing_flag", NC_BYTE, 2, dimid_levels, 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; index_2D[0] = collocation_num; index_2D[1] = 0; num_vals_2D[0] = 1; num_vals_2D[1] = 118; // Unpack and save the Sonde ID sonde_id[0] = buffer[29] / 100; sonde_id[1] = buffer[29] % 100; sonde_id[2] = buffer[30] / 100; sonde_id[3] = buffer[30] % 100; sonde_id[4] = buffer[31] / 100; sonde_id[5] = buffer[31] % 100; sonde_id[6] = ' '; sonde_id[7] = ' '; sonde_id[8] = '\0'; string[0] = sonde_id; if (retval = nc_put_vara_string(nc_group_id, vid_sonde_id, index, num_vals, (const char **)string)) ERR(retval); // Latitude and longitude latitude = buffer[39] / 128.0; longitude = buffer[40] / 128.0; writeVariableFloat(nc_group_id, vid_lat, index, num_vals, latitude); writeVariableFloat(nc_group_id, vid_lon, index, num_vals, longitude); // Date and time year = buffer[35]; month = buffer[36]; day = buffer[37]; hour = buffer[38] / 100; minute = buffer[38] % 100; second = 0; yyyymmdd = (year * 10000) + (month * 100) + day; hhmmss = (hour * 10000) + (minute * 100) + second; 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); } // Save the station elevation, report type, instrument type // and terrain writeVariableShort(nc_group_id, vid_elevation, index, num_vals, buffer[41]); writeVariableShort(nc_group_id, vid_report_type, index, num_vals, buffer[42]); if ((buffer[43] < 0) || (buffer[43] > 299)) writeVariableShort(nc_group_id, vid_instrument_type, index, num_vals, -32768); else writeVariableShort(nc_group_id, vid_instrument_type, index, num_vals, buffer[43]); if ((sonde_id[0] < '0') || (sonde_id[0] > '9')) writeVariableByte(nc_group_id, vid_terrain, index, num_vals, (char)4); else if (buffer[44] == 0) writeVariableByte(nc_group_id, vid_terrain, index, num_vals, (char)0); else if (buffer[44] == 1) writeVariableByte(nc_group_id, vid_terrain, index, num_vals, (char)1); else if (buffer[44] == 2) writeVariableByte(nc_group_id, vid_terrain, index, num_vals, (char)2); else writeVariableByte(nc_group_id, vid_terrain, index, num_vals, (char)-128); // Lowest and highest pressures if (buffer[45] != -32768) writeVariableFloat(nc_group_id, vid_lo_interp_press, index, num_vals, (buffer[45]/10.0)); else writeVariableFloat(nc_group_id, vid_lo_interp_press, index, num_vals, missing_float); if (buffer[46] != -32768) writeVariableFloat(nc_group_id, vid_hi_interp_press, index, num_vals, (buffer[46]/10.0)); else writeVariableFloat(nc_group_id, vid_hi_interp_press, index, num_vals, missing_float); if (buffer[47] != -32768) writeVariableByte(nc_group_id, vid_qc_flag, index, num_vals, (char)buffer[47]); else writeVariableByte(nc_group_id, vid_qc_flag, index, num_vals, (char)-128); writeVariableByte(nc_group_id, vid_nprovs_qc, index, num_vals, (char)0); if (buffer[48] != -32768) writeVariableByte(nc_group_id, vid_vert_ext, index, num_vals, (char)buffer[48]); else writeVariableByte(nc_group_id, vid_vert_ext, index, num_vals, (char)-128); if ((buffer[50] >= 0) && (buffer[50] <= 3)) writeVariableByte(nc_group_id, vid_superad, index, num_vals, (char)buffer[50]); else writeVariableByte(nc_group_id, vid_superad, index, num_vals, (char)-128); if (buffer[51] != -32768) writeVariableByte(nc_group_id, vid_inversion, index, num_vals, (char)buffer[51]); else writeVariableByte(nc_group_id, vid_inversion, index, num_vals, (char)-128); // if (buffer[52] != -32768) // writeVariableByte(nc_group_id, vid_tpw_cat, index, num_vals, (char)buffer[52]); // else // writeVariableByte(nc_group_id, vid_tpw_cat, index, num_vals, (char)-128); // if (buffer[66] != -32768) // writeVariableByte(nc_group_id, vid_inversion_type, index, num_vals, (char)buffer[66]); // else // writeVariableByte(nc_group_id, vid_inversion_type, index, num_vals, (char)-128); writeVariableFloat(nc_group_id, vid_tropo_press, index, num_vals, (buffer[152]/1.0)); writeVariableFloat(nc_group_id, vid_surf_press, index, num_vals, (buffer[153]/1.0)); if (buffer[154] != -32768) writeVariableFloat(nc_group_id, vid_surf_temp, index, num_vals, (buffer[154]/64.0)); else writeVariableFloat(nc_group_id, vid_surf_temp, index, num_vals, missing_float); if (buffer[155] != -32768) writeVariableFloat(nc_group_id, vid_surf_wvmr, index, num_vals, (float)(exp(buffer[155]/1024.0))); else writeVariableFloat(nc_group_id, vid_surf_wvmr, index, num_vals, missing_float); if (buffer[156] != -32768) writeVariableFloat(nc_group_id, vid_surf_dwpt, index, num_vals, (buffer[156]/64.0)); else writeVariableFloat(nc_group_id, vid_surf_dwpt, index, num_vals, missing_float); if (buffer[157] != -32768) writeVariableFloat(nc_group_id, vid_low_wvmr, index, num_vals, (float)(exp(buffer[157]/1024.0))); else writeVariableFloat(nc_group_id, vid_low_wvmr, index, num_vals, missing_float); if (buffer[158] != -32768) writeVariableFloat(nc_group_id, vid_high_wvmr, index, num_vals, (float)(exp(buffer[158]/1024.0))); else writeVariableFloat(nc_group_id, vid_high_wvmr, index, num_vals, missing_float); if (buffer[162] != -32768) writeVariableFloat(nc_group_id, vid_tpw, index, num_vals, (buffer[162]/100.0)); else writeVariableFloat(nc_group_id, vid_tpw, index, num_vals, missing_float); // Layer precipitable water for (n=0; n<18; n++) { if (buffer[163+n] != -32768) lpw[n] = buffer[163+n] / 100.0; else lpw[n] = -32768; } index_2D[0] = collocation_num; index_2D[1] = 0; num_vals_2D[0] = 1; num_vals_2D[1] = 18; writeArrayFloat(nc_group_id, vid_lpw, index_2D, num_vals_2D, lpw); // More values if (buffer[61] != -32768) writeVariableByte(nc_group_id, vid_temp_gap, index, num_vals, (char)buffer[61]); else writeVariableByte(nc_group_id, vid_temp_gap, index, num_vals, (char)-128); // Merge the standard and significant level data merged_levels = NULL; for (n=0; n<18; n++) { // Process this level unless all of the data are missing if ((buffer[194+n] != -32768) || (buffer[212+n] != -32768) || (buffer[230+n] != -32768) || (buffer[248+n] != -32768) || (buffer[266+n] != -32768) || (buffer[284+n] != -32768) || (buffer[302+n] != -32768) || (buffer[320+n] != -32768) || (buffer[338+n] != -32768) || (buffer[356+n] != -32768) || (buffer[374+n] != -32768) || (buffer[410+n] != -32768)) { new_level = (struct merged_data*)malloc(sizeof (struct merged_data)); new_level->std_or_sig = STANDARD; new_level->pressure = std_level_pressures[n]; if (buffer[194+n] == -32768) new_level->temp = -32768.0; else new_level->temp = (buffer[194+n] / 10.0) + 273.13; if (buffer[212+n] == -32768) new_level->radcor_temp = -32768.0; else new_level->radcor_temp = (buffer[212+n] / 10.0) + 273.13; if (buffer[230+n] == -32768) new_level->background_temp = -32768.0; else new_level->background_temp = (buffer[230+n] / 10.0) + 273.12; if (buffer[248+n] == -32768) new_level->wvmr = -32768.0; else new_level->wvmr = dwptToWvmr(new_level->pressure, ((buffer[248+n]/10.0)+273.15)); if (buffer[266+n] == -32768) new_level->radcor_wvmr = -32768.0; else new_level->radcor_wvmr = dwptToWvmr(new_level->pressure, ((buffer[266+n]/10.0)+273.15)); if (buffer[284+n] == -32768) new_level->background_wvmr = -32768.0; else new_level->background_wvmr = dwptToWvmr(new_level->pressure, (buffer[284+n]/1000.0)); if (buffer[302+n] == -32768) new_level->drift_time = -32768.0; else new_level->drift_time = buffer[302+n] / 100.0; if (buffer[320+n] == -32768) new_level->drift_latitude = -32768.0; else new_level->drift_latitude = buffer[320+n] / 128.0; if (buffer[338+n] == -32768) new_level->drift_longitude = -32768.0; else new_level->drift_longitude = buffer[338+n] / 128.0; new_level->pressure_qc = -32768; new_level->temp_qc = buffer[356+n]; new_level->humidity_qc = buffer[374+n]; new_level->missing_flag = buffer[410+n]; new_level->next = NULL; // Insert the new level into the sorted merged array if (merged_levels == NULL) { merged_levels = new_level; } else { ptr = merged_levels; prev_ptr = NULL; level_inserted = FALSE; while ((ptr != NULL) && (level_inserted == FALSE)) { if (new_level->pressure < ptr->pressure) { if (prev_ptr == NULL) { new_level->next = merged_levels; merged_levels = new_level; } else { new_level = prev_ptr->next; prev_ptr->next = new_level; } level_inserted = TRUE; } else if (ptr->next == NULL) { ptr->next = new_level; level_inserted = TRUE; } else { prev_ptr = ptr; ptr = ptr->next; } } } // else (merged_levels != NULL... } // if (buffer[356+n... } // for (n=0... // Significant level data for (n=0; nstd_or_sig = SIGNIFICANT; if (buffer[429+n] != -32768) pressure = buffer[429+n] / 10.0; else pressure = -32768.0; new_level->pressure = pressure; if (buffer[529+n] == -32768) new_level->temp = -32768.0; else new_level->temp = (buffer[529+n] / 10.0) + 273.13; if (buffer[629+n] == -32768) new_level->radcor_temp = -32768.0; else new_level->radcor_temp = (buffer[629+n] / 10.0) + 273.13; if (buffer[729+n] == -32768) new_level->background_temp = -32768.0; else new_level->background_temp = (buffer[729+n] / 10.0) + 273.12; if (buffer[829+n] == -32768) new_level->wvmr = -32768.0; else new_level->wvmr = dwptToWvmr(new_level->pressure, ((buffer[829+n]/10.0)+273.15)); if (buffer[929+n] == -32768) new_level->radcor_wvmr = -32768.0; else new_level->radcor_wvmr = dwptToWvmr(new_level->pressure, ((buffer[929+n]/10.0)+273.15)); if (buffer[1029+n] == -32768) new_level->background_wvmr = -32768.0; else new_level->background_wvmr = dwptToWvmr(new_level->pressure, (buffer[1029+n]/1000.0)); if (buffer[1129+n] == -32768) new_level->drift_time = -32768.0; else new_level->drift_time = buffer[1129+n] / 100.0; if (buffer[1229+n] == -32768) new_level->drift_latitude = -32768.0; else new_level->drift_latitude = buffer[1229+n] / 128.0; if (buffer[1329+n] == -32768) new_level->drift_longitude = -32768.0; else new_level->drift_longitude = buffer[1329+n] / 128.0; new_level->pressure_qc = buffer[1429+n]; new_level->temp_qc = buffer[1529+n]; new_level->humidity_qc = buffer[1629+n]; new_level->missing_flag = buffer[1829+n]; new_level->next = NULL; // Insert the new level into the sorted merged array if (merged_levels == NULL) { merged_levels = new_level; } else { ptr = merged_levels; prev_ptr = NULL; level_inserted = FALSE; while ((ptr != NULL) && (level_inserted == FALSE)) { if (new_level->pressure < ptr->pressure) { if (prev_ptr == NULL) { new_level->next = merged_levels; merged_levels = new_level; } else { new_level->next = prev_ptr->next; prev_ptr->next = new_level; } level_inserted = TRUE; } else if (ptr->next == NULL) { ptr->next = new_level; level_inserted = TRUE; } else { prev_ptr = ptr; ptr = ptr->next; } } } // else (merged_levels != NULL... } // if (buffer[1537+n... } // for (n=0... // Put the merged data into arrays in preparation of writing the data // to the netCDF file for (n=0; n<118; n++) { merged_std_sig[n] = (char)-128; merged_press_qcs[n] = (char)-128; merged_temp_qcs[n] = (char)-128; merged_humid_qcs[n] = (char)-128; merged_missing_flags[n] = (char)-128; merged_pressures[n] = -32768.0; merged_temps[n] = -32768.0; merged_radcor_temps[n] = -32768.0; merged_back_temps[n] = -32768.0; merged_wvmrs[n] = -32768.0; merged_radcor_wvmrs[n] = -32768.0; merged_back_wvmrs[n] = -32768.0; merged_drift_times[n] = -32768.0; merged_drift_lats[n] = -32768.0; merged_drift_lons[n] = -32768.0; } level = -1; ptr = merged_levels; while (ptr != NULL) { level++; if (ptr->std_or_sig != -32768) merged_std_sig[level] = (char)ptr->std_or_sig; if (ptr->pressure_qc != -32768) merged_press_qcs[level] = (char)ptr->pressure_qc; if (ptr->temp_qc != -32768) merged_temp_qcs[level] = (char)ptr->temp_qc; if (ptr->humidity_qc != -32768) merged_humid_qcs[level] = (char)ptr->humidity_qc; if (ptr->missing_flag != -32768) merged_missing_flags[level] = (char)ptr->missing_flag; merged_pressures[level] = ptr->pressure; merged_temps[level] = ptr->temp; merged_radcor_temps[level] = ptr->radcor_temp; merged_back_temps[level] = ptr->background_temp; merged_wvmrs[level] = ptr->wvmr; merged_radcor_wvmrs[level] = ptr->radcor_wvmr; merged_back_wvmrs[level] = ptr->background_wvmr; merged_drift_times[level] = ptr->drift_time; merged_drift_lats[level] = ptr->drift_latitude; merged_drift_lons[level] = ptr->drift_longitude; prev_ptr = ptr; ptr = ptr->next; free(prev_ptr); } // Write the arrays to the netCDF file index_2D[0] = collocation_num; index_2D[1] = 0; num_vals_2D[0] = 1; num_vals_2D[1] = 118; writeArrayByte(nc_group_id, vid_std_sig_flags, index_2D, num_vals_2D, merged_std_sig); writeArrayByte(nc_group_id, vid_press_qcs, index_2D, num_vals_2D, merged_press_qcs); writeArrayByte(nc_group_id, vid_temp_qcs, index_2D, num_vals_2D, merged_temp_qcs); writeArrayByte(nc_group_id, vid_humid_qcs, index_2D, num_vals_2D, merged_humid_qcs); writeArrayByte(nc_group_id, vid_missing_flags, index_2D, num_vals_2D, merged_missing_flags); writeArrayFloat(nc_group_id, vid_press, index_2D, num_vals_2D, merged_pressures); writeArrayFloat(nc_group_id, vid_temps, index_2D, num_vals_2D, merged_temps); writeArrayFloat(nc_group_id, vid_radcor_temps, index_2D, num_vals_2D, merged_radcor_temps); writeArrayFloat(nc_group_id, vid_back_temps, index_2D, num_vals_2D, merged_back_temps); writeArrayFloat(nc_group_id, vid_wvmrs, index_2D, num_vals_2D, merged_wvmrs); writeArrayFloat(nc_group_id, vid_radcor_wvmrs, index_2D, num_vals_2D, merged_radcor_wvmrs); writeArrayFloat(nc_group_id, vid_back_wvmrs, index_2D, num_vals_2D, merged_back_wvmrs); writeArrayFloat(nc_group_id, vid_drift_times, index_2D, num_vals_2D, merged_drift_times); writeArrayFloat(nc_group_id, vid_drift_lats, index_2D, num_vals_2D, merged_drift_lats); writeArrayFloat(nc_group_id, vid_drift_lons, index_2D, num_vals_2D, merged_drift_lons); } // 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