/* Name- AddMirsToNprovs.c Language- C Type- MAIN Version- 1.0 Date- 2/28/2026 Programmer- Mike Pettey (STC) Function- This program extracts data from MIRS granules and collocates the data to selected collocations times and locations. */ #include #include #include #include #include #include #include #include #include #include "uthash.h" #include "mirs_collocator.h" //#define MAX_TIME_DIFF 6.0 #define MAX_TIME_DIFF 6.0 * 60.0 * 60.0 #define MAX_DISTANCE_DIFF 200.0 #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #define DEG_TO_RAD (M_PI / 180.0) //#define TRUE 0 //#define FALSE 1 int createCollocationArray(int date_to_process); int addSondeLevelDataToCollocationArray(int in_id, int date_to_process); int createOutputFile(int date_to_process, int nprovs_platform_id, char *nprovs_platform_name, int in_id); int copyAttributes(int in_id, int out_id); void defineDimensionsAndVariables(int nc_id, int num_collocations); void copyPreviousPlatforms(int in_id, int out_id, int platform_id); void copyNetCDFGroup(int in_id, int out_id, int group_id, int date_group_id); void doCollocations(int out_id, int date_to_process, char *tarball_name); void findMatchingGranules(char *tarball_name); int copyMirsDataToOutputFile(struct collocation_data *collocations, int num_collocations, struct FileEntry *hash_table, char *tarball_name, int out_id); float calculateTimeDifference(int date1, int time1, int date2, int time2); float calculateDistanceDifference(float lat1, float lon1, float lat2, float lon2); long convertDateAndTimeToEpochTime(int date, int time); void convertEpochTimeToDateAndTime(double epoch_time, int *yr, int *md, int *hr, int *ms); void unpackGranuleDateAndTime(char *time_string, int* date, int* time); int fileStartsWith(char *file_name, char *token); int fileEndsWith(char *file_name, char *token); void addFileToHash(const char *name); struct collocation_data *collocations; struct FileEntry *collocated_files_hash = NULL; int num_collocations; int out_date_group_id, mirs_id; int main(int argc, char *argv[]) { int date_to_process, nprovs_platform_id, out_id; int in_id, max_sonde_levels, coll; int attributes_copied; int num_collocations_copied, actual_collocations; char nprovs_platform_name[100]; // struct FileEntry *collocated_files_hash = NULL; // Print an initial message printf("\nCollocating MIRS data with NPROVS\n\n"); // Unpack the date to process date_to_process = atoi(argv[1]); // Unpack the platform ID and platform name nprovs_platform_id = atoi(argv[2]); sprintf(nprovs_platform_name, "%s", argv[3]); printf("Date to process: %d\n\n", date_to_process); printf("NPROVS Platform ID: %d\n", nprovs_platform_id); printf("NPROVS Platform Name: %s\n\n", nprovs_platform_name); // Create the collocation array that will contain information about each // collocation in_id = createCollocationArray(date_to_process); // Add the sonde drift level data to the collocation array // max_sonde_levels = addSondeLevelDataToCollocationArray(in_id, date_to_process); // Create and initialize the output netCDF file out_id = createOutputFile(date_to_process, nprovs_platform_id, nprovs_platform_name, in_id); // Set the closest collocation values to their initial default values for (coll=0; coll 0) addFileToHash(collocations[coll].closest_snd_granule); if (strlen(collocations[coll].closest_img_granule) > 0) addFileToHash(collocations[coll].closest_img_granule); if (strlen(collocations[coll].closest_snow_granule) > 0) addFileToHash(collocations[coll].closest_snow_granule); } } //printf("\n"); actual_collocations = 0; for (coll=0; coll= date_range_start) && (granule_start_epoch_time <= date_range_end)) || ((granule_end_epoch_time >= date_range_start) && (granule_end_epoch_time <= date_range_end))) { // Read the number of scan lines and field of views for this granule retval = nc_inq_dimid(nc_id, "Scanline", &dim_id); retval = nc_inq_dimlen(nc_id, dim_id, &dim_length); num_scanlines = (int)dim_length; retval = nc_inq_dimid(nc_id, "Field_of_view", &dim_id); retval = nc_inq_dimlen(nc_id, dim_id, &dim_length); num_fovs = (int)dim_length; num_footprints = num_scanlines * num_fovs; // Read the scanline date and time from the granule and use them to calculate // the epoch time for each footprint footprint_times = (double*)malloc(num_footprints*sizeof(double)); scanline_year = (short*)malloc(num_scanlines*sizeof(short)); scanline_month = (short*)malloc(num_scanlines*sizeof(short)); scanline_day = (short*)malloc(num_scanlines*sizeof(short)); scanline_hour = (short*)malloc(num_scanlines*sizeof(short)); scanline_minute = (short*)malloc(num_scanlines*sizeof(short)); scanline_second = (short*)malloc(num_scanlines*sizeof(short)); retval = nc_inq_varid(nc_id, "ScanTime_year", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_year); retval = nc_inq_varid(nc_id, "ScanTime_month", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_month); retval = nc_inq_varid(nc_id, "ScanTime_dom", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_day); retval = nc_inq_varid(nc_id, "ScanTime_hour", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_hour); retval = nc_inq_varid(nc_id, "ScanTime_minute", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_minute); retval = nc_inq_varid(nc_id, "ScanTime_second", &var_id); retval = nc_get_var_short(nc_id, var_id, scanline_second); fp_index = -1; for (scan=0; scanfilename, name, sizeof(s->filename)); HASH_ADD_STR(collocated_files_hash, filename, s); } } // end of file