/*************************************************************** LLGRID.C Within a time range, this program produces a list of profile times and positions in the vicinity of latitude and longitude grid crossings. The grid is specified as a starting position and an increment for each dimension. Eric Firing 88-04-16 Thu 05-04-1989 Modified to print out the decimal day for each range boundary and the length of the range in minutes. This requires a change in the control file. Thu 01-18-1990 Modified to print longitudes within +/- 180 (JR) 96/05/20 - EF - Modified to print a warning about missing positions, but to ignore them when calculating the time ranges. ---------------------------------------------------------------- control file structure: dbname: (e.g. WEP) output: (file name) year_base: (e.g. 1989) step_size: (number of profiles to advance) lat_origin: lat_increment: lon_origin: lon_increment: time_ranges: (list of YMDHMS time pairs:) (yy/mm/dd hh:mm:ss) to (yy/mm/dd hh:mm:ss) . . add_time_ranges: skip_to: ****************************************************************/ #include #include "geninc.h" #include "ioserv.h" /* PARAMETER_LIST_ENTRY_TYPE, get_parameters(), check_error() */ #include "use_db.h" /* check_db*() */ #define TRUE 1 #define FALSE 0 #define MIN_PER_DAY 1440.0 #define sqr(x) (x)*(x) #define good_float(x) ( (x) < ADJ_BADFLOAT ) static int year_base; static FILE_NAME_TYPE dbname, out_filename, dbpath; static int STEPS; static DOUBLE_LL_TYPE d_origin, d_increment; /* degrees, for parameter input */ static int make_grid(); static PARAMETER_LIST_ENTRY_TYPE parameters[] = { { " dbname:", PATH_FMT, dbpath, TYPE_STRING }, { " output:", PATH_FMT, out_filename, TYPE_STRING }, { " year_base:", " %d", &year_base, TYPE_INT }, { " step_size:", " %d", &STEPS, TYPE_INT }, { " latitude ", NULL, NULL, 0 }, { " origin:", " %lf", &(d_origin.lat), TYPE_DOUBLE }, { " increment:", " %lf", &(d_increment.lat), TYPE_DOUBLE }, { " longitude ", NULL, NULL, 0 }, { " origin:", " %lf", &(d_origin.lon), TYPE_DOUBLE }, { " increment:", " %lf", &(d_increment.lon), TYPE_DOUBLE }, { NULL, NULL, NULL, 0 } }; /* parameters[] */ static OPTION_TYPE options[] = { { "end", 0 , NULL , NULL }, { "time_ranges:" , 0 , make_grid , NULL }, { "add_time_ranges:", 1 , make_grid , NULL }, { "skip_to" , 0 , skip_to , NULL }, { "dbname:", TYPE_STRING, op_get_param , dbpath }, { "output:", TYPE_STRING, op_get_param , out_filename }, { "year_base:", TYPE_INT , op_get_param , (char *) &year_base }, { "step_size:", TYPE_INT , op_get_param , (char *) &STEPS }, { "lat_origin:", TYPE_DOUBLE, op_get_param , (char *) &(d_origin.lat) }, { "lat_increment:", TYPE_DOUBLE, op_get_param , (char *) &(d_increment.lat) }, { "lon_origin:", TYPE_DOUBLE, op_get_param , (char *) &(d_origin.lon) }, { "lon_increment:", TYPE_DOUBLE, op_get_param , (char *) &(d_increment.lon) }, { NULL, 0 , NULL, NULL, } }; int main(int argc, char *argv[]) { FILE *fp_cnt; fp_cnt = get_fpcnt(argc, argv); dbname[0] = 0; out_filename[0] = 0; year_base = 1993; STEPS = 1; d_origin.lat = 0.0; d_increment.lat = 1.0; d_origin.lon = 0.0; d_increment.lon = 1.0; while (!execute_options(fp_cnt, options, ECHO)) ; return 0; } static int make_grid(FILE *fp_cnt, char *dummy, int append_flag) { FILE *fp_out; int IERR; YMDHMS_TIME_TYPE start, end, /* for time range */ this_time, last_time; /* previous, current profile time */ HUN_LL_TYPE this_position, last_position; HUN_LL_TYPE origin, increment; /* hundredths of a second */ long this_longitude, last_longitude = 0L; /* longitude within +/- 180 */ int first_time; /* flag for local loop control */ double start_day, end_day; last_position.lon = last_position.lat = 0L; strcpy(dbname, dbpath); printf("dbname: %s\n",dbname); check_dbopen(1, dbname, READ_ONLY, DIR_IN_MEMORY); if (append_flag == 1) fp_out = check_fopen(out_filename,"a"); else fp_out = check_fopen(out_filename,"w"); if ( fp_out == NULL ) { fprintf(stderr, " ERROR: Unable to open output file %s.\n", out_filename); return (-1); } origin.lat = to_hundredths(d_origin.lat); increment.lat = to_hundredths(d_increment.lat); origin.lon = to_hundredths(d_origin.lon); increment.lon = to_hundredths(d_increment.lon); /* ensure that the position relative to the origin will be positive */ origin.lon -= (360 * 360000L); origin.lat -= (90 * 360000L); /* ---> Print the header. */ fprintf(fp_out, "/* Grid boundaries for:\n"); print_parameters(fp_out, parameters, NULL, " "); fprintf(fp_out, "\n*/"); /* ---> Start the loop through time ranges listed in the control file. */ while (get_time_range(fp_cnt, &start, &end) == 1) { check_dbsrch(TIME_SEARCH, (char *)&start); fprintf(fp_out, "\n/* "); print_time_range(fp_out, &start, &end); print_time_range(stdout, &start, &end); fprintf(fp_out, " */"); first_time = TRUE; IERR = 0; /* ---> Start the loop through profiles within the time range. */ while (!IERR && check_time(&this_time, &start, &end)) { get_hun_latlon(&this_position); this_longitude = this_position.lon; if (this_longitude != BADLONG) { if (this_longitude > 64800000L) this_longitude -= 129600000L; if (this_longitude > 64800000L) this_longitude -= 129600000L; if (first_time) { start_day = year_day(&this_time, year_base); fprintf(fp_out, "\n"); write_ymdhms_time(fp_out, &this_time); fprintf(fp_out, " /* %7.3f %8.3f, %12.5f (begin time range) */", to_degrees(this_position.lat), to_degrees(this_longitude), start_day); first_time = FALSE; } else /* This is not the first profile in a time range. */ { /* Has a boundary been crossed? */ if ( ((this_position.lon - origin.lon)/increment.lon != (last_position.lon - origin.lon)/increment.lon) || ((this_position.lat - origin.lat)/increment.lat != (last_position.lat - origin.lat)/increment.lat)) { end_day = year_day(&last_time, year_base); fprintf(fp_out, "to\n"); write_ymdhms_time(fp_out, &last_time); fprintf(fp_out, " /* %7.3f %8.3f, %12.5f; %4.0f min */", to_degrees(last_position.lat), to_degrees(last_longitude), end_day, (end_day - start_day)*MIN_PER_DAY); fprintf(fp_out, "\n"); /* find start day for NEXT segment */ start_day = year_day(&this_time, year_base); write_ymdhms_time(fp_out, &this_time); fprintf(fp_out, " /* %7.3f %8.3f, %12.5f */", to_degrees(this_position.lat), to_degrees(this_longitude), start_day); } } /* end of "not first profile" */ last_position = this_position; last_longitude = this_longitude; last_time = this_time; } /* end of "if (this_longitude != BADLONG)" */ else { printf("\nWarning: missing position at "); write_ymdhms_time(stdout, &this_time); } DBMOVE(&STEPS, &IERR); /* IERR is checked at the start of the loop */ } /* end of loop through profiles within a time range */ end_day = year_day(&last_time, year_base); fprintf(fp_out, "to\n"); write_ymdhms_time(fp_out, &last_time); fprintf(fp_out, " /* %7.3f %8.3f, %12.5f; %4.0f min (end time range) */", to_degrees(last_position.lat), to_degrees(last_longitude), end_day, (end_day - start_day)*MIN_PER_DAY); fprintf(fp_out, "\n\n"); } /* end of loop through time ranges read from control file */ fclose(fp_out); DBCLOSE(&IERR); check_error(IERR, "DBCLOSE"); return (1); }