/* @(#) File name: fci2_sw.c Release: 1.2 Date: 1/13/94, 10:02:19 */ /**************************************************************************** PROGRAM: fci2_sw PURPOSE/DESCRIPTION: Program fci2_sw contains the sample read routines for all FIRE Cirrus II data sets in ASCII format. The functions in this program are named closely after the applicable data sets. For example, function noaa_wndprfl() is the sample read routine for the NOAA windprofiles data set. This program will produce the following C executables: class_sonde, csu_prt6, csu_sondes, csu_station1, csu_station2, csu_wndprfl, doplr_lidar, maps, noaa_wndprfl, nws_sonde, pams, and raman_lidar. All executables allow multiple input files as input arguments and process them in sequence. With the exception of doplr_lidar, all output are sent to the standard output device. The output can be redirected to a file for reviewing. The doplr_lidar has two parts of data: profile directory and the profile records. The profile directory are written to the standard output device, but the profile records are written to a file. Any error in reading the data will be written to the standard error device. ALGORITHM: None. INVOCATION: prgram_name [-s] data_file1 data_file2 ... WHERE is one of the 12 executable files mentioned in the purpose section. are the data file names (not granule names) of an applicable data set. <-s> is an optional option that is ONLY applied to the maps data set. It has to be the first argument in the argument list, if invoked. FILE/RECORD REFERENCES: None. EXTERNAL ROUTINES: None. NOTES: The rationale behind these read routines are to provide a flexible and easy to use read routine for the user. Hopefully, this program can allow users to know the format of the variables in the ASCII files, and customize to suit their own needs in viewing the data with the graphics tools. *****************************************************************************/ #include #include "fci2_sw.h" /**** Since HP 300/400 series does not support rint(), and nint() functions, these function are defined as macros when this program module is run under the HP UX. When the user compile this module, add "-D hpux" in the compilation command. ****/ #ifdef HPUX # define rint(x) ((int) (x < 0.0) ? (x - 0.5) : (x + 0.5)) #else extern double rint(); #endif #ifdef HPUX # define nint(x) ((int) rint(x)) #endif /**** Local library functions, provided in fci2_lib.c file. ****/ extern int julian_day(), str_trim(); extern void interrupt_cat(), hd_sondes(); extern char *strdup(); main (argc, argv) int argc; char **argv; { void class_sonde(), csu_prt6(), csu_sondes(), csu_station(), csu_wndprfl (); void doplr_lidar(), maps(), noaa_wndprfl(), nws_sonde(), pams(), raman_lidar(); if (signal (SIGINT, SIG_IGN) != SIG_IGN) signal (SIGINT, interrupt_cat); (void) signal (SIGTERM, interrupt_cat); #ifdef CLASS_SONDE (void) class_sonde (argc, argv); #endif #ifdef CSU_PRT6 (void) csu_prt6 (argc, argv); #endif #ifdef CSU_SONDES (void) csu_sondes (argc, argv); #endif #ifdef STATION1 (void) csu_station (argc, argv); #endif #ifdef STATION2 (void) csu_station (argc, argv); #endif #ifdef CSU_WND (void) csu_wndprfl (argc, argv); #endif #ifdef DOPLR_LIDAR (void) doplr_lidar (argc, argv); #endif #ifdef MAPS (void) maps (argc, argv); #endif #ifdef NOAA_WND (void) noaa_wndprfl (argc, argv); #endif #ifdef NWS_SONDE (void) nws_sonde (argc, argv); #endif #ifdef PAMS (void) pams (argc, argv); #endif #ifdef RAMAN_LIDAR (void) raman_lidar (argc, argv); #endif exit (0); } /**************************************************************************** FUNCTION: class_sonde () PURPOSE/DESCRIPTION: Function class_sonde reads in NCAR class sondes data. Note that among the three versions of a given sounding that NCAR class data have, Langley DAAC has only "i" version, which is the sounding data with data interpolated to every 5mb level. INVOCATION: (void) class_sonde (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple class sonde data files. For example, class_sonde ib252317.iol ib291343.cof will read two files: ib252317.iol, and ib291343.cof. FILE/RECORD REFERENCES: Each class sonde file is named `imddhhMM.sta', where m is the month (values [1-9, a-c];b=Nov), dd the day of month, hh the hour sounding start (GMT was used for CaPE), MM the minute for sounding start (hhMM is approximate), and sta the 3-letter station ID. EXTERNAL ROUTINES: None. NOTES: 1.) There are 21 variables defined in the data structure class_data in fci2_sw.h file. Also, see README.fci2 for variables descriptions. 2.) Output format string for the 21 variables are as follows: "%7.2f%8.3f%6.1f%7.2f%7.2f%6.1f%6.1f%9.4f%7.2f%7.2f%6.1f%6.1f %6.1f%6.1f%8.0f%7.2f%7.2f%8.3f%8.3f%9.4f%9.4f" *****************************************************************************/ void class_sonde (argc, argv) int argc; char **argv; { FILE *fptr; char filename[200], buf[250], ddhhmm[7]; char *base, *head[3], *lines[12], comma; char datatype[20], project[40], sitetype[20], site_id[20], sys_opr[40]; char wnd_type[20], processor[30], wnd_smooth[30], obs_src[50]; char lon_str[20], lat_str[20], lon[20], lat[20], alt[20], comment[250]; int year, month, day, hour, minute, second; int i, j, k, l, nrec; class_data dat; /* Defined in file fci2_sw.h */ i = 0; while (i++ < (argc-1)) { l = 0; strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } base = strrchr (filename, '/'); base = (base == NULL) ? filename : (++base); /* Read in HEADER information. */ for (j = 0; j < 12; j++) { fgets (buf, sizeof(buf), fptr); str_trim (buf, 0); lines[l++] = strdup (buf); } /* Decode field info. in each line, comma (,) is used to be a * field separator. */ /* Read in Data Type, the first line in the file */ strcpy (datatype, &lines[0][PARAM_POS]); /* Read in project ID, the second line in the file */ strcpy (project, &lines[1][PARAM_POS]); /* Read in launch site type and site ID, the 3rd line in the file */ sscanf (&(lines[2][PARAM_POS]), "%[^,]%c%s", sitetype, &comma, site_id); /* Read in launch location (lon, lat, alt), the 4th line in the file */ sscanf (&(lines[3][PARAM_POS]), "%[^,]%c%[^,]%c%[^,]%c%[^,]%c%s", lon_str, &comma, lat_str, &comma, lon, &comma, lat, &comma, alt); /* Read in gmt launch time (y,m,d,hh:mm:ss), the 5th line in the file */ sscanf (&(lines[4][PARAM_POS]), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d", &year, &comma, &month, &comma, &day, &comma, &hour, &comma, &minute, &comma, &second); sprintf (ddhhmm, "%02d%02d%02d", day, hour, minute); if (strncmp (&(base[2]), ddhhmm, 6) != 0) { fprintf (stderr,"WARNING: Time in the data file = %s, but file name is %s\n", ddhhmm, base); /** continue; **/ } /* Skip the 6th line in the file containing Sonde Type, Sonde ID, * Sensor ID/Tx frequency; and the 7th line in the file containing * Met Processor/Met Smoothing. */ /* Read in Winds Type/Processor/Smoothing, the 8th line in the file */ sscanf (&(lines[7][PARAM_POS]), "%[^,]%c%[^,]%c%[^,]", wnd_type, &comma, processor, &comma, wnd_smooth); /* Read in Pre-launch Surface Obs Source, the 9th line in the file */ strcpy (obs_src, &lines[8][PARAM_POS]); /* Read in System Operator/Comments, the 10th line in the file */ sscanf (&(lines[9][PARAM_POS]), "%[^,]", sys_opr); strcpy (comment, &(lines[9][PARAM_POS+strlen(sys_opr)+1])); /* Skip two lines (l1th and 12th lines) containing only / */ for (j = 0, k = 0; j < 3; j++) { fgets (buf, sizeof (buf), fptr); str_trim (buf, 0); head[k++] = strdup (buf); } nrec = 0; /***** Read in data record. ****/ while (fgets (buf, sizeof (buf), fptr) != NULL) { str_trim (buf, 0); sscanf (buf, "%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%d", &dat.sec, &dat.pressure, &dat.c_temp, &dat.dewpoint, &dat.rhumidity, &dat.uwind, &dat.vwind, &dat.wnd_speed, &dat.wnd_dir, &dat.dz, &dat.longitude, &dat.latitude, &dat.range, &dat.angle, &dat.altitude, &dat.qp, &dat.qt, &dat.qh, &dat.qu, &dat.qv, &dat.quv); /** Commented out the following two lines if the column headings are not ** desired in the output page. **/ if ((nrec++) % 40 == 0) (void) hd_sondes (filename, l, lines, k, head); /* printf ("%s\n", buf); */ printf (CLASS_FMT, dat.sec, dat.pressure, dat.c_temp, dat.dewpoint, dat.rhumidity, dat.uwind, dat.vwind, dat.wnd_speed, dat.wnd_dir, dat.dz, dat.longitude, dat.latitude, dat.range, dat.angle, dat.altitude, dat.qp, dat.qt, dat.qh, dat.qu, dat.qv, dat.quv); } printf ("** Total records read in file %s = %d **\n", filename, nrec); /* Clear the buffer */ for (j = 0; j < l; j++) free (lines[j]); for (j = 0; j < k; j++) free (head[j]); fclose (fptr); } } /**************************************************************************** FUNCTION: csu_prt6 () PURPOSE/DESCRIPTION: CUS_PRT6 reads in CSU PRT-6 data taken during the FIRE cirrus IFO Phase II Experiment. This program reads the record one at a time in the data file, validates julian day and time (hour-second) values within each record, then sends the validated record to the standard output device. The PRT-6 was not run in a continuous mode. Data was collected during the period from Nov. 18, 1991 (day 322) to Dec. 7, 1991 (day 341) when operating. Data was sampled at 5 seconds interval. The site was at 37 deg 18 min N and 95 deg 07 min W. WARNING: There are temporal gaps in the data. When there are temporal gaps in the data, a '+' sign will be added to the end of the brightness temperature value. INVOCATION: (void) csu_prt6 (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple csu prt6 data files. For example, if the executable is csu_prt6, then, csu_prt6 ci2_prt6_911118 ci2_prt6_911203 will read two files: ci2_prt6_911118, and ci2_prt6_911203. FILE/RECORD REFERENCES: The data files are named ci2_prt6_yymmdd, where yy is the year, mm the month (only 11 and 12 are valid), and dd the day (UTC) when the data were collected. EXTERNAL ROUTINES: None. NOTES: There are four input variables in the PRT-6 data files. They are: 1) julian day (UTC), 2) hour-minute (UTC), 3) second (UTC), 4) equivalent brightness temperature (K) The output file has the following information on each page: line 1: csu prt6 file name, e.g., ci2_prt6_911118 line 2: column header line 3: blank line 4 through 54: data. The data field and its data type are: 1) day (UTC), integer; 2) HHmm (UTC), where HH is the hour, mm is the minute, integer; 3) second (UTC), float, up to 4 digits precision 4) equivalent brightness temperature (K), float, up to 3 digits precision. *****************************************************************************/ void csu_prt6 (argc, argv) int argc; char **argv; { FILE *fptr; void hd_csu_prt6(); char filename[200], hr_min[16]; int i=0, day, hour, minute, nrec; float second, float_day, bright_temp, last_time, curr_time; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } nrec = 0; last_time = 0.0; /**** Read the data record one by one. ****/ while (fscanf (fptr, "%f %s %f %f", &float_day, hr_min, &second, &bright_temp) != EOF) { if (atoi(hr_min) >= 100) { /* Has hour and minute values. */ hour = atoi(hr_min) / 100; minute = atoi (hr_min) % 100; } else { hour = 0; minute = atoi (hr_min); } day = (int)float_day; curr_time = hour * 3600 + minute * 60 + second; /** Commented out the following line if the three header lines are not ** desired in the output. **/ if (nrec % 55 == 0) (void) hd_csu_prt6 (filename); /** The following printf statement prints out the 4 data fields. **/ if ((nrec++ > 0) && (nint (curr_time - last_time) != 5)) printf ("%03d %8d %07.4f %.3f +\n", day, atoi(hr_min), second, bright_temp); else printf ("%03d %8d %07.4f %.3f\n", day, atoi(hr_min), second, bright_temp); last_time = curr_time; } printf ("Total records read in file %s = %d\n", filename, nrec); fclose (fptr); } } void hd_csu_prt6 (filename) char *filename; { printf ("File name: %s\n", filename); printf ("%3s %8s %7s %s\n\n","DAY","HHmm","SECOND","BRIGHTNESS_TEMP"); } /**************************************************************************** FUNCTION: csu_sondes () PURPOSE/DESCRIPTION: CUS_SONDES reads in FIRE-II CSU Rawindsonde data at Parsons KG&E Power Plant. Sondes were launched primarily in support of surface radiation measurements for the period from Nov 13, 1991 (Julian day 317) to Dec. 6, 1991 (Julian day 340). The site was at 37 deg 18 min N and 95 deg 07 min W. Data points with values of -9999.0 are bad. WARNING: Because of problems tracking the sonde, the angles of the tracking antenna should be used with caution. They are provided to allow a calculation of an approximate location of the sonde. INVOCATION: (void) csu_sondes (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple csu sondes data files. For example, if the executable is csu_sondes, then, csu_sondes 911113.1828s 911205.1425s will read two files: 911113.1828s and 911205.1425s. FILE/RECORD REFERENCES: Data files are named YYMMDD.hhmms where YY is the year, MM the month, DD the day, hh the hour, and mm the minute of the launch time. The first record in the file should start with the same time as the launch time. EXTERNAL ROUTINES: julian_day() NOTES: 1.) There are 10 variables in the input file. They are: julian day (UTC), hour (UTC), minute (UTC), second (UTC), geopotential height (km), pressure (mb), temperature (K), relative humidity (%), azimuth angle (deg), elevation angle (deg) 2.) The output file has the following format: line 1: csu sondes file name, e.g., 911125.0009s line 2: Bad data value, which is -9999.00 line 3: blank line 4 through 54: data. The same ten fields as in the input file. 3.) Except for the time values, format for the other six variables are F9.3. *****************************************************************************/ void csu_sondes (argc, argv) int argc; char **argv; { FILE *fptr; void hd_csu_sondes(); char filename[200], *s, *str; int i=0, jul, year, month, day, doy, hr, min, nrec; float sec, geo_height, pressure, temp, humidity, azimuth, elevation; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", argv[i]); continue; } nrec = 0; s = strrchr (filename, '/'); str = (s == NULL) ? &(filename[0]) : (++s); sscanf (str, "%2d%2d%2d", &year, &month, &day); jul = julian_day (year, month, day); /**** Read the csu_sondes data records. ****/ while (fscanf (fptr, "%d%d%d %f %f%f%f%f%f%f", &doy, &hr, &min, &sec, &geo_height, &pressure, &temp, &humidity, &azimuth, &elevation) != EOF) { if (doy != jul) { if ((doy * 24 * 60 + hr * 60 + min) <= (jul * 24 * 60)) printf ("ERROR?? file %s, Rec. num = %d, Julian day = %d; doy=%d\n", filename, nrec, jul, doy); /* Otherwise, the data coverage cross the midnight. */ } /** Commented out the following line if the column heading is not desired ** in the output. **/ if ((nrec++) % 55 == 0) (void) hd_csu_sondes (filename); /** The following 3 printf statements print out all ten data fields. **/ printf ("%-4d %-2d %-02d %5.2f ", doy, hr, min, sec); printf ("%9.3f %9.3f %9.3f ", geo_height, pressure, temp); printf ("%9.3f %9.3f %9.3f\n", humidity, azimuth, elevation); } printf ("** Total records read in file %s = %d **\n\f", filename, nrec); fclose (fptr); } } void hd_csu_sondes (filename) char *filename; { int i; static char *fields[2][10] = { {"Day", "Hr", "Min", "Sec. ", "Geop.", "Pressure", "Temp", "Relative", "Azimuth", "Elev."}, {" ", " ", " ", " ", "height(km)", "(mb)", "(K)", "hum. (%)", "(degree)", "(degree)"} }; /** Column headings **/ printf ("\f\nFile name: %s\nBad data value: %.1f\n", filename, BAD_DATA); printf ("%3s %2s %3s %5s ",fields[0][0],fields[0][1],fields[0][2],fields[0][3]); for (i = 4; i < 10; i++) printf("%9s ", fields[0][i]); printf ("\n%3s %2s %3s %5s ",fields[1][0],fields[1][1],fields[1][2],fields[1][3]); for (i = 4; i < 10; i++) printf("%9s ", fields[1][i]); printf ("\n\n"); } /**************************************************************************** FUNCTION: csu_station () PURPOSE/DESCRIPTION: Function csu_station reads the Fire CI2 CSU Station1 and CSU Station2 data. Instantaneous values of the parameters were collected every 2 minutes for the period from 11 Nov 1991 (day 315) to 8 Dec 1991 (day 342). The site was at 37 deg 18 min N and 95 deg 07 min W. Since station1 and station2 has different number of variables (19 vs. 11), conditional compilation is needed to generate two executables (one for reading station1 data, the other for reading station2 data) from the same source code (See NOTES 1 below). NOTE that the executable for station1 can read multiple station1 data files, but not the combinations of station1 and station2 data files. Same statements apply to the station2 executable. This program reads the record one at a time in the data file, validates julian day and the time (hour- minute) values within each record, then sends the validated record to the standard output device. INVOCATION: (void) csu_station1 (argc, argv); or (void) csu_station2 (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple Par station data file names. For example, if the executable is csu_station1, then, csu_station1 ci2_s1kge_911113 ci2_s1kge_911121 will read two files: ci2_s1kge_911113, and ci2_s1kge_911121. FILE/RECORD REFERENCES: Station1 data files are named ci2_s1kge_yymmdd, where yy is the year, mm the month, and dd the day. Station 2 data files are named ci2_s2tri_yymmdd, where yy is the year, mm the month, and dd the day. Missing data and extreme values are marked with -9999.0. EXTERNAL ROUTINES: None. NOTES: 1.) To build executable for csu_station1: cc -DSTATION1 -o csu_station1 ... And, To build executable for station2: cc -o csu_station2 .... 2.) There are 19 variables in the CSU station1 data file, and 11 varaibles in the CSU station2 data file. The variables with units and estimated precision (in units) are listed under section 5 of the README.fci2 file. 3.) The output file has the following format: line 1: station1 or station2 file name, e.g., ci2_s1kge_911113 line 2: Bad data value, which is -9999.0 line 3: blank line 4: column heading line 5: units for the variables line 6: blank line 7 through 44: data. The same fields as in the input file. *****************************************************************************/ /********************************************************************** * There are 8 direct solar filters related variables for CSU station1 * data. They are put in a data structure called "dir_solar". **********************************************************************/ void csu_station (argc, argv) int argc; char **argv; { dir_solar st; /** Defined in fci2_sw.h file **/ FILE *fptr; void hd_stations(); float ftime, wnd_spd, wnd_dir, temp, humidity, sol_irr; float ninf_irr, inf_irr, dome_tmp, sink_tmp, hr, min; char filename[200], buf[400], *s; int i=0, nrec, day, hhmm, hour, minute; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } nrec = 0; /** Read in all 19 variables for station1, or 11 variables for station2. **/ while (fgets (buf, sizeof (buf), fptr) != NULL) { #ifdef STATION1 sscanf (buf, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %d", &ftime, &wnd_spd, &wnd_dir, &temp, &humidity, &sol_irr, &ninf_irr, &inf_irr, &dome_tmp, &sink_tmp, &st.yfilter, &st.rfilter, &st.drfilter, &st.n90filter, &st.n0filter, &st.n30filter, &st.n60filter, &st.nfilter, &hhmm); #else sscanf (buf, "%f %f %f %f %f %f %f %f %f %f %d", &ftime, &wnd_spd, &wnd_dir, &temp, &humidity, &sol_irr, &ninf_irr, &inf_irr, &dome_tmp, &sink_tmp, &hhmm); #endif /** Commented out the following line if the header printout is not necessary. **/ if (nrec % 45 == 0) (void) hd_stations (filename); /* Check the first column value (ftime) and the last column value (hhmm). */ hour = (hhmm >= 100) ? (hhmm/100) : 0; minute = (hhmm >= 100) ? (hhmm % 100) : hhmm; hr = (ftime - (int)ftime) * 24; min = (float) rint ((hr - (int)hr) * 60); /* Because of floating point rounding and truncation, the following * two lines of codes are used to smoothe possible margin of errors. */ hr = (int)hr + (min / 60); min = (min >= 60.0) ? (min - 60.0) : min; /* Check the hour and minute values. */ if (hhmm != (int)MISSING) { if (((int)hr != hour) || ((int)min != minute)) fprintf (stderr,"ERROR: Rec.# = %d, Julian time =%f, hr/min =%2d2%d\n", nrec+1, ftime, hour, minute); } printf ("%10.6f %10.6f %10.6f %10.6f ", ftime, wnd_spd, wnd_dir, temp); printf ("%10.6f %10.6f %10.6f ", humidity, sol_irr, ninf_irr); printf ("%10.6f %10.6f %10.6f ", inf_irr, dome_tmp, sink_tmp); #ifdef STATION1 printf ("%12.6f %12.6f %12.6f ",st.yfilter,st.rfilter,st.drfilter); printf ("%12.6f %12.6f %12.6f ",st.n90filter,st.n0filter,st.n30filter); printf ("%12.6f %12.6f ",st.n60filter,st.nfilter); #endif printf ("%4d\n", hhmm); nrec++; } printf ("Total %d lines processed in file %s\n", nrec, filename); fclose (fptr); } } void hd_stations (filename) char *filename; { int i; static char *fields[2][10] = { {"Time","Wnd Speed","Wnd Dir"," Temp","Humidity","SolTot IRR", "NI_IRR","INF_IRR","Dome Temp","Sink Temp"}, {"UTC"," (m/s) ","degrees"," (C) "," (%) ","W/m**2","W/m**2","W/m**2", " (K) "," (K) "} }; #ifdef STATION1 static char *st1_fld[2][8] = { {"Y_filter","R_filter","DR_filter","90_sec NF","0_sec NF","30_sec NF", "60_sec NF","90_sec NF"}, {"W/m**2","W/m**2","W/m**2", "W/m**2","W/m**2","W/m**2","W/m**2","W/m**2"} }; #endif printf("\fFile Name: %s\nMissing data value: %.1f\n\n", filename, MISSING); for (i = 0; i < 10; i++) printf("%10s ", fields[0][i]); #ifdef STATION1 for (i = 0; i < 8; i++) printf("%12s ", st1_fld[0][i]); #endif printf("%-10s\n", "HourMinute"); for (i = 0; i < 10; i++) printf("%10s ", fields[1][i]); #ifdef STATION1 for (i = 0; i < 8; i++) printf("%12s ", st1_fld[1][i]); #endif printf("%-10s\n\n", "HHMM"); } /**************************************************************************** FUNCTION: csu_wndprfl () PURPOSE/DESCRIPTION: Funciton csu_wndprfl reads in CSU wind profiler data, which are single cycle data collected at Parsons, KS from 2 Nov 1991 7 Dec 1991. INVOCATION: (void) csu_wndprfl (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple CSU windprofiles data file names. For example, csu_wndprfl 91120410.wp 91120422.wp will read two files: 91120410.wp, and 91120422.wp. FILE/RECORD REFERENCES: The file names of the data is YYMMDDHH.wp where YY is the year, MM the month, DD the day, and HH the hour the data were collected. BAD data value for u and v variables: -9999.0. EXTERNAL ROUTINES: None. NOTES: This data has been through a quality control program using the Weber and Wuertz QC subroutines. Thresholds of 4m/s and 5% size of largest pattern was used on combined-low/high-mode-opposing-beams profile. Note vertical velocity was assumed to be zero. (28% of the dataset was marked as "bad".) There are four input variables in the CSU wind profiler data files. They are listed in order as follows: 1) minute, 2) height (km above MSL), 3) u (m/s), 4) v (m/s) The first line in the file is the header line, which contains year, month, day, hour information. See README.fci2 file for the variable formats. The output of the CSU wind profiler data has the following format on each page (assuming 56 lines per page output): line 1: file name; e.g., 91120410.wp line 2: YY:MM:DD:HH line 3: blank line 4: column heading line 5: blank line 6 through 56: data 1) dd:hh:mm:ss, where dd is the julian day, hh is the hour, mm is the minute, ss is the second. 2) equivalent brightness temperature (K) *****************************************************************************/ void csu_wndprfl (argc, argv) int argc; char **argv; { FILE *fptr; void hd_csu_wnd (); char filename[200], header_str[100], date_str[16], *s; int i=0, year, month, day, hour, second, nrec; float height, u_wnd, v_wnd; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } nrec = 0; s = strrchr (filename, '/'); s = (s == NULL) ? filename : ++s; fgets (header_str, sizeof(header_str), fptr); str_trim (header_str, 0); if (strncmp (header_str, s, strlen (header_str)) != 0) fprintf (stderr,"File (%s) NOT consistent with the header (%s).\n", filename, header_str); sscanf (header_str, "%2d%2d%2d%2d", &year, &month, &day, &hour); sprintf (date_str, "%02d:%02d:%02d:%02d", year, month, day, hour); while (fscanf(fptr,"%d %f %f %f",&second,&height,&u_wnd,&v_wnd) != EOF) { /** Commented out the following line if the column headings are not ** desired in the output page. **/ if ((nrec++) % 55 == 0) (void) hd_csu_wnd (filename, date_str); printf ("%2d %7.3f %9.3f %9.3f\n", second, height, u_wnd, v_wnd); } printf ("Total of %d records read in file %s\n", nrec, filename); fclose (fptr); } } void hd_csu_wnd (filename, date_time) char *filename, *date_time; { int i; static char *fields[4] = {"Min.", "Height", "U_WND (m/s)", "V_WND (m/s)"}; printf ("\fFilename: %s\ndate_time: %s\n\n", filename, date_time); for (i = 0; i < sizeof (fields[0]); i++) printf ("%s ", fields[i]); printf ("\n"); } /**************************************************************************** FUNCTION: doplr_lidar () PURPOSE/DESCRIPTION: Function doplr_lidar reads the doppler lidar data sets. The Doppler lidar experiment objective was to obtain lidar measurements of relative backscatter signal intensity and radial velocity from cirrus clouds to study their microphysical and radiative properties. This data set provides Vertical profiles (approx. 1.5 - 20.0 km AGL) data. The profile directory are written to the standard output device, but the profile records are written to a file. The profile records are processed by the function "read_vad_profile". This will allow the easier implementation of extracting subsets of the profile records. INVOCATION: (void) doplr_lidar (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple doppler lidar data file names. For example, doplr_lidar fire2vad28nova fire2vad21nova will read two files: fire2vad28nova, and fire2vad21nova. FILE/RECORD REFERENCES: All except one doppler lidar data file is named `fire2vadDDMMMa', where DD is the day of month, and MMM the month (either nov or dec). The one file is named fire2vad91a, which contains the annual data. Each file contains the directory of all profiles in this file, followed by the profile records. EXTERNAL ROUTINES: None. NOTES: 1. See README.fci2 file for a list of variables in the directory line, and the variables in each profile record. *****************************************************************************/ void doplr_lidar (argc, argv) int argc; char **argv; { FILE *fptr; void hd_doplr_lidar (); char filename[200], buf[120], *s; int i=0, beg_num=0, end_num; /* The following belongs to VAD profile file directory line. */ int prof_num, date, time; float elevation, beg_azimuth, end_azimuth; int sweep_num, sweep_dir, qa_flag, site_num, beg_rec_num, end_rec_num; char mswitch[12]; int beg_gate, end_gate, noisegate, energy_flg, process_date, process_time; float mean_vel, mean_power, threshold, range_noisegate, noise_in_gate; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr,"ERROR: Can't open file:\t %s\n", filename); continue; } /** Read the directory section **/ printf ("\n\nDirectory of profiles within the file \"%s\"\n", filename); for (i = 0; i < 3; i++) { fgets (buf, sizeof (buf), fptr); str_trim (buf, 0); (void) hd_doplr_lidar ((int)PROFILE_DESC, buf, (FILE *)NULL); } while (fgets (buf, sizeof (buf), fptr) != NULL) { str_trim (buf, 0); for (s = &buf[0]; (*s == ' ') && (*s != '\0'); s++) ; if (!isdigit (*s)) break; sscanf (s, "%d%d%d%f%f%f%d%d%d%d%d%d", &prof_num, &date, &time, &elevation, &beg_azimuth, &end_azimuth, &sweep_num, &sweep_dir, &qa_flag, &site_num, &beg_rec_num, &end_rec_num); (void) hd_doplr_lidar ((int)PROFILE_DESC, buf, (FILE *)NULL); } end_num = prof_num; /* Skip over file contents descriptions. */ while (fgets (buf, sizeof (buf), fptr) != NULL) { for (s = &buf[0]; (*s == ' ') && (*s != '\0'); s++) ; if (isdigit (*s)) break; str_trim (buf, 0); (void) hd_doplr_lidar ((int)PROFILE_DESC, buf, (FILE *)NULL); } read_vad_profile (fptr, filename, buf, beg_num, end_num); fclose (fptr); } } /**************************************************************************** FUNCTION: read_vad_profile () PURPOSE/DESCRIPTION: Function read_vad_profile reads all profile records in the input file. All profile records are sent to an output file. The output file is automatically generated with the name containing the input file name and the process id as the file name extension. NOTE: Because the process id for each invocation of the executable is different under Unix system, the output file name will be different at each run. INVOCATION: status = read_vad_profile (fptr, fname, s, beg_num, end_num) WHERE - I is the pointer of the doppler lidar data file. - I is the file name of the doppler lidar data file. This parameter is used to construct the output file name for the profile records. For example, if the process id is 9360, the output file name will be fname.9360. - I holds the contents of the directory line. - I is the begining profile number to start reading the profile records. - I is the end profile number for reading the profile records. - O return 0 when there is no error, otherwise a -1 is returned. FILE/RECORD REFERENCES: A profile record starts with one directory line, followed by two header lines, followed by multiple profile records. EXTERNAL ROUTINES: None. NOTES: 1. Except for the quality flag, output format for the other eight profile parameters are "%9.3f". Parameters are defined in the data structure vad_profile in the fci2_sw.h header file. 2. In order to keep the same command line invocation convention the same across all FIRE-CI2 data sets, subsetting on the profile records were deleted from the original codes. *****************************************************************************/ int read_vad_profile (fptr, fname, s, beg_num, end_num) FILE *fptr; char *fname, *s; int beg_num, end_num; { vad_profile vad; /* Defined in fci2_sw.h file */ void hd_doplr_lidar (); FILE *outptr; char buf[120], out_file[200], *str; int prof_num, date, time, i; float elevation, beg_azimuth, end_azimuth; int sweep_num, sweep_dir, qa_flag, site_num, beg_rec, end_rec; if (fptr == (FILE *)NULL) { fprintf (stderr,"ERROR: Invalid file pointer. CAN'T continue.\n"); return (-1); } strcpy (buf, s); str = strrchr (fname, '/'); str = (s == NULL) ? fname : str++; sprintf (out_file, "%s.%d", str, getpid()); if ((outptr = fopen (out_file, "w")) == NULL) outptr = stdout; do { /* Extract the Directory line of a profile. */ sscanf (buf, "%d%d%d%f%f%f%d%d%d%d%d%d", &prof_num, &date, &time, &elevation, &beg_azimuth, &end_azimuth, &sweep_num, &sweep_dir, &qa_flag, &site_num, &beg_rec, &end_rec); if ((beg_num > prof_num) || (end_num < prof_num)) { /* Skip over header line 1 and 2, and the records. */ for (i = 0; i < (end_rec - beg_rec + 2); i++) fgets (buf, sizeof (buf), fptr); } else { /* Print directory line */ str_trim (buf, 0); (void) hd_doplr_lidar ((int)PROFILE_DAT, buf, outptr); /* Read the header line 1 and header line 2. */ for (i = 0; i < 2; i++) { fgets (buf, sizeof (buf), fptr); str_trim (buf, 0); (void) hd_doplr_lidar ((int)PROFILE_DESC, buf, outptr); } (void) hd_doplr_lidar ((int) PROFILE_FLD, outptr); /**** Read the profile records. ****/ for (i = 0; i < (end_rec - beg_rec); i++) { fgets (buf, sizeof (buf), fptr); sscanf (buf, "%f%f%f%f%f%f%f%d%f", &vad.altitude, &vad.wndspeed, &vad.wnd_dir, &vad.sig2noise, &vad.good_pts, &vad.rms_err, &vad.vvelocity, &vad.qa_flag, &vad.energy); str_trim (buf, 0); (void) hd_doplr_lidar ((int)PROFILE_DAT, buf, outptr); } } } while ((fgets (buf, sizeof (buf), fptr) != NULL) && (prof_num < end_num)); fclose (outptr); return (0); } void hd_doplr_lidar (va_alist) va_dcl { va_list var_str; int i, ndx; FILE *ptr; char *s; static char *fields[2][9] = { {"Altitude", "Wind", "Wind", "Signal/", "Good pts", "RMS", "Velocity", " Flag", "Energy"}, {" ", "Speed", "Dir.", "Noise", " (%)", "error", "Diverg.", " ", "Per Alt."} }; va_start (var_str); ndx = va_arg (var_str, int); switch (ndx) { case (int)PROFILE_DESC: s = va_arg (var_str, char *); ptr = va_arg (var_str, FILE *); if (ptr == NULL) printf ("%s\n", s); else fprintf (ptr, "%s\n", s); break; case (int)PROFILE_FLD: ptr = va_arg (var_str, FILE *); for (i = 0; i < 7; i++) fprintf (ptr, "%9s", fields[0][i]); fprintf (ptr, "%5s%9s\n", fields[0][i++], fields[0][i]); for (i = 0; i < 7; i++) fprintf (ptr, "%9s", fields[1][i]); fprintf (ptr, "%5s%9s\n\n", fields[1][i++], fields[1][i]); break; case (int)PROFILE_DAT: s = va_arg (var_str, char *); ptr = va_arg (var_str, FILE *); fprintf (ptr, "%s\n", s); break; } va_end (var_str); } /**************************************************************************** FUNCTION: maps () PURPOSE/DESCRIPTION: Function maps reads FIRE-CI2 maps data, and optionally reads the terrain and the latlon data files. Functions maps(), maps_ terrain(), and maps_latlon() together perform these functions. Function maps prints out 6 variables at different level as the data are read and the min. max. values for each variables at the end of processing. Function maps_terrain prints out the min. max. values for the terrain data. Function maps_latlon prints out the min. max. values of all variables's latitude and longitude. MAPS uses an 81 (x direction) x 62 (y direction) horizontal Cartesian mesh with 60 km grid spacing on an Arakawa-A grid which has all variables defined at each grid node. The information for each horizontal field consists of a header line containing the name of the variable and the vertical coordinate, followed by 62 groups of 81 field values. Each group of 81 field values represents one x direction row of grid node values, beginning with the southernmost row in the domain, and proceeding northward with succeeding groups. The 81 values are ordered from the west to the east edges of the grid domain, and are listed in the file using 13 numbers per line, with the last line in each group containing 3 values. There are 10 characters per field value, and each value is right-justified with 3 decimal digits following an explicit decimal point, as in Fortran f10.3 format. Hence, the very first field value will be the pressure on the sigma=1 surface at the southwest corner of the domain. The very last field value will be the V wind component on the virtual theta=410K surface at the northeast corner of the domain. See README.fci2 file for the descriptions of 6 data variables. INVOCATION: (void) maps (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name, multiple pams data files, and an optional argument "-s". For example, maps ci2_maps_911124_03 ci2_maps_911118_00 will read two files: ci2_maps_911124_03, and ci2_maps_911118_00 maps -s ci2_maps_911124_03 ci2_maps_911118_00 will prompt the user to enter the file names of the terrain and latitude/longitude data. After the user enters the file names, it will print out the min. max. of the terrain file and the min. max. of the latlong file. It then reads two files: ci2_maps_911124_03, and ci2_maps_911118_00. FILE/RECORD REFERENCES: Each MAPS analysis file contains 65250 lines and 7608900 bytes in ASCII format. The file naming convention for the MAPS analysis files is: ci2_maps_yymmdd_hh, where yy is the year, mm the month, dd the day, and hh the starting hour when the data were collected. EXTERNAL ROUTINES: None. NOTES: Sorting each variable's field values can also get the min, max values with the standard function qsort() and customized comparison function floatcomp(). After sorting, the 1st and the last elements will be the minimum and maximum value, respectively. The drawbacks are the processing speed is much slower and the contents of the array that stores the field values will be overwritten because qsort() writes in the same array. In this case, if the original order of field values are desired, they should be placed in another array to avoid being overwritten. The following line of codes demonstrate this method: (void) qsort ((void *)&(var[j].fld[0][0][0]), total, sizeof (float), floatcomp); *****************************************************************************/ static int floatcomp(); void maps (argc, argv) int argc; char **argv; { map_var *var; /* Array for the field values of all variables */ char filename[MAXPATHLEN+1], stars[80], equal, buf[200]; char fnames[400], flatlon[200], fterrain[200]; static char optflag[]={"-s"}; int i, j, x, y, z, total; FILE *fptr; float maximum, minimum; total = PTS_X * PTS_Y * PTS_Z; var = (map_var *) calloc (NUM_VAR, sizeof (map_var)); i = 0; /** Process the terrain and latlon data file to get the min, max ** values for the maps data set. **/ strcpy (filename, argv[1]); if (strcmp (filename, optflag) == 0) { i++; printf ("Enter MAPS terrain file name, space, followed by "); printf ("MAPS latitude/longitude file name, then hit a return.\n"); gets (fnames); sscanf (fnames, "%s %s", flatlon, fterrain); maps_terrain (flatlon); maps_latlon (fterrain); } /*** Process MAPS 3-D fields for 6 variables ***/ while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr,"ERROR: Can't open file:\t %s\n", filename); continue; } /** MAPS data files is organized as follows: ** line 1: ********* varialbe 1 at sigma (or theta) = v_coord1 ********** ** line 2 - 435: every 7 lines contain 81 values in X direction for variable 1 ** line 436: ******** variable 2 at sigma (or theta) = v_coord1 ********** ** line 437 - 870: every 7 lines contain 81 values in X direction for variable 2 ** ..... ** line 2616: ******* variable 1 at sigma (or theta) = v_coord2 ********** ** line 2617 - 3051: every 7 lines contain 81 values in X direction for variable 1 ** ..... **/ for (z = 0; z < PTS_Z; z++) { for (j = 0; j < NUM_VAR; j++) { fgets (buf, sizeof(buf), fptr); sscanf (buf, "%[ *]%8c%[^=]%c%g%s", stars, var[j].var_name, stars, &equal, &(var->vcoord), stars); printf ("Input %s at vertical %.3f\n", var[j].var_name, var->vcoord); for (y = 0; y < PTS_Y; y++) { /* Grid points in Y dir. */ for (x = 0; x < PTS_X; x++) { /* Grid points in X dir. */ fscanf (fptr, "%g", &(var[j].fld[x][y][z])); } } fgets (buf, sizeof(buf), fptr); } } for (j = 0; j < NUM_VAR; j++) { minimum = MAXFLOAT; maximum = MINFLOAT; for (x = 0; x < PTS_X; x++) { for (y = 0; y < PTS_Y; y++) { for (z = 0; z < PTS_Z; z++) { minimum = fmin (minimum, var[j].fld[x][y][z]); maximum = fmax (maximum, var[j].fld[x][y][z]); } } } printf ("%s, minimum = %g, maximum = %g\n", var[j].var_name, minimum, maximum); } fclose (fptr); } free (var); exit (0); } static int floatcomp (a, b) float *a, *b; { if ((*a - *b) < 0.0) return (-1); else if ((*a - *b) == 0.0) return (0); else if ((*a - *b) > 0.0) return (1); } /**************************************************************************** FUNCTION: maps_terrain () PURPOSE/DESCRIPTION: Function maps_terrain reads in terrain height 2-D field. It computes and report min, max of terrain height field. INVOCATION: status = maps_terrain (filename); WHERE - I the file name of the maps terrain data file. - O returns 0 when there is no error, otherwise, a -1 is returned. FILE/RECORD REFERENCES: EXTERNAL ROUTINES: None. NOTES: *****************************************************************************/ int maps_terrain (filename) char *filename; { FILE *fptr; float terr_ht[PTS_X][PTS_Y]; int x, y, total; total = PTS_X * PTS_Y; if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr,"ERROR: Can't open terrain file:\t %s\n", filename); return (-1); } for (y = 0; y < PTS_Y; y++) { for (x = 0; x < PTS_X; x++) { fscanf (fptr, "%g", &(terr_ht[x][y])); } } /** Compute and report min, max of terrain height field **/ (void) qsort ((void *)&(terr_ht[0][0]), total, sizeof (float), floatcomp); printf ("Terrain height min = %g, max = %g\n", terr_ht[0][0], terr_ht[PTS_X-1][PTS_Y-1]); fclose (fptr); return (0); } /**************************************************************************** FUNCTION: maps_latlon () PURPOSE/DESCRIPTION: Function maps_latlon reads in latitude and longitude 2-D fields. The input file is organized as the first 434 lines are the latitude data, next 434 lines are the longitude data. It computes and report min, max of latitude and longitude field. INVOCATION: status = maps_latlon (filename); WHERE - I the file name of the maps latitude and longitude data file. - O returns 0 when there is no error, otherwise, a -1 is returned. FILE/RECORD REFERENCES: EXTERNAL ROUTINES: None. NOTES: *****************************************************************************/ int maps_latlon (filename) char *filename; { FILE *fptr; float lat[PTS_X][PTS_Y], lon[PTS_X][PTS_Y]; int x, y, total; total = PTS_X * PTS_Y; if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr,"ERROR: Can't open latlon file:\t %s\n", filename); return (-1); } for (y = 0; y < PTS_Y; y++) { for (x = 0; x < PTS_X; x++) fscanf (fptr, "%g", &(lat[x][y])); } for (y = 0; y < PTS_Y; y++) { for (x = 0; x < PTS_X; x++) fscanf (fptr, "%g", &(lon[x][y])); } /** Compute and report min, max of latitude and longitude fields **/ (void) qsort ((void *)&(lat[0][0]), total, sizeof (float), floatcomp); (void) qsort ((void *)&(lon[0][0]), total, sizeof (float), floatcomp); printf ("Latitude min = %g, max = %g\n", lat[0][0], lat[PTS_X-1][PTS_Y-1]); printf ("Longitude min = %g, max = %g\n", lon[0][0], lon[PTS_X-1][PTS_Y-1]); fclose (fptr); return (0); } /**************************************************************************** FUNCTION: nws_sonde () PURPOSE/DESCRIPTION: NWS_SONDE reads in FIRE-II NWS_IN and NWS_OUT sondes data. This function reads the data, one level at a time, then prints out to the standard output device. Both nws_in_sonde, and nws_out_sonde data sets have the same file and record organizations, and contains the same variables. Thus, they share this read routine. INVOCATION: (void) nws_sonde (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple Par station data file names. For example, nws_sonde ELP.1687 OUN.1655 will read two files: ELP.1687, and OUN.1655. FILE/RECORD REFERENCES: Data files are named SSS.aaaa where SSS is the station name, and aaaa is the ascent number. EXTERNAL ROUTINES: str_trim(), hd_sondes(); NOTES: 1.) The input and output files are organized as follows: 9 lines of header information, followed by a blank line, followed by a line of field headings, followed by a line of field units. The nws sonde data starts with the 13th line in the file. See README.fci2 file for the detailed descriptions of variables. The header variables are listed in order as follows: project name, principle investigator, WMO station indentifier, station call letters, station name and state, ascent number, nominal time of ascent, nominal date of ascent, launch time, launch date, radiosonde manufacture, radiosonde type, balloon size, weather at time of launch, number of levels in sonde, quality control flag. A nws_in_sonde, or nws_out_sonde record starts with the number of level, followed by 21 variables, and ends with the same number of level. Except for two "number of level" variables, the rest of the 21 variables are grouped in a data structure. All of the data variables have data type 'float'. The purpose of defining them in a data structure is to make sure data will be stord in the consecutive memory. 2.) The output format for the data is defined as follows: "%3d%7.2f%8.3f%6.1f%7.2f%7.2f%6.1f%6.1f%9.4f%7.2f%7.2f%6.1f%6.1f%6.1f %6.1f%8.0f%7.2f%7.2f%8.3f%8.3f%9.4f%9.4f%3d\n" *****************************************************************************/ /* There are 21 data variables, which are defined in the nws_data data structure * in the fci2_sw.h file */ void nws_sonde (argc, argv) int argc; char **argv; { FILE *fptr; char filename[200], buf[180], unuse[25], colon; char *ext, *base, *lines[10], *head[2]; char project[20], author[80], station[30], wmo_id[10], stn_id[10]; char asc_date[9], asc_time[10], nom_time[10], nom_date[9]; char sonde_maker[6], sonde_type[6], ssize[6], qa_label[10]; int i=0, j, k, l, m, nrec; int asc_num, weather, nlevel; nws_data dat; while (i++ < (argc-1)) { l = 0; strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } ext = strrchr (filename, '.'); if (ext == NULL) printf ("ERROR: File name (%s) missing ascent number.\n"); base = strrchr (filename, '/'); base = (base == NULL) ? filename : (++base); /* Read in header information. */ /* Read in project title and principle investigator. */ for (k = 0; k < 10; k++) { fgets (buf, sizeof(buf), fptr); str_trim (buf, 0); lines[l++] = strdup (buf); } strcpy (project, &lines[0][10]); strcpy (author, &lines[1][10]); /* Read in WMO identification number and station call letters. */ sscanf (lines[2], "%*10c %s%s%[ ]%n", wmo_id, stn_id, unuse, &j); strcpy (station, &lines[2][j]); if (strncmp (stn_id, base, strlen(base)-strlen(ext)-1) != 0) printf ("ERROR: File (%s), station call letters (%s) unmatch\n", filename, stn_id); /* Read in ascent number, as well as nominal time and date. */ sscanf (lines[3], "%*10c %d %s %s", &asc_num, nom_time, nom_date); /* Read in ascent number, as well as ascent time and date. */ sscanf (lines[4], "%*10c %d %s %s", &asc_num, asc_time, asc_date); /* Read in radiosonde manufacture, radiosonde type, and balloon size */ sscanf (lines[5], "%*10c %s %s %s", sonde_maker, sonde_type, ssize); /* Read in observed weather conditions */ sscanf (lines[6], "%*10c%d", &weather); /* Read in number of levels */ sscanf (lines[7], "%[^:]%c%d", unuse, &colon, &nlevel); /* Read in quality control label */ sscanf (lines[8], "%[^:]%c%s", unuse, &colon, qa_label); for (j = 0, m = 0; j < 2; j++) { fgets (buf, sizeof (buf), fptr); str_trim (buf, 0); head[m++] = strdup (buf); } nrec = 0; /* Read in data record. */ while (fgets (buf, sizeof (buf), fptr) != NULL) { str_trim (buf, 0); sscanf (buf, "%d%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%d", &k, &dat.min, &dat.height, &dat.pressure, &dat.c_temp, &dat.k_temp, &dat.rh_water, &dat.rh_ice, &dat.humidity, &dat.dewpoint, &dat.frost_pt, &dat.wnd_speed, &dat.wnd_dir, &dat.zonal, &dat.meridional, &dat.asc_rate, &dat.lapse_rate, &dat.tmp_lapse, &dat.lon_dist, &dat.lat_dist, &dat.lon_pos, &dat.lat_pos, &k); /** Commented out the following two lines if the column headings are not ** desired in the output page. **/ if ((nrec++) % 40 == 0) (void) hd_sondes (filename, l, lines, m, head); /*** printf ("%s\n", buf); ***/ printf (NWS_FMT, k, dat.min, dat.height, dat.pressure, dat.c_temp, dat.k_temp, dat.rh_water, dat.rh_ice, dat.humidity, dat.dewpoint, dat.frost_pt, dat.wnd_speed,dat.wnd_dir, dat.zonal, dat.meridional, dat.asc_rate, dat.lapse_rate, dat.tmp_lapse, dat.lon_dist, dat.lat_dist, dat.lon_pos, dat.lat_pos, k); } if (nrec != nlevel) fprintf (stderr,"WARNING: Rec. num = %d, in the file %s", nrec, filename); printf ("** Total records read in file %s = %d **\n", filename, nrec); /* Clear the buffer */ for (j = 0; j < l; j++) free (lines[j]); for (j = 0; j < m; j++) free (head[j]); fclose (fptr); } } /**************************************************************************** FUNCTION: pams () PURPOSE/DESCRIPTION: PAMS reads in pams data taken during the FIRE-II Experiment. FIRE-II was approximately 25 days long, hence 25 data sets for each of 6 sites where pams data were collected. The data are in ASCII. This function can process multiple input files. For each input file, reading in the header line, followed by the records. For each record, reading in the observation # (record #), followed by 12 parameters, and quality flag (QA) for each parameter. INVOCATION: (void) pams (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple pams data files. For example, if the executable is pams, then, pams st6nov18.data st1nov17.data st4dec07.data will read three files: st6nov18.data, st1nov17.data, st4dec07.data. FILE/RECORD REFERENCES: Data files are named stNMMMDD.data, where N is the station number, MMM is the month (3-letter code, either nov or dec), and DD is the day. Each file starts with a header line followed by 1440 data records. Missing value code is -99.00 for all parameters. EXTERNAL ROUTINES: None. NOTES: 1.) The Fortran format for the header line is: (a8,i2,2x,3(i2),3(f10.4)), See README.fci2 for the variables in header line and the in data records. The meanings of the quality flags for the 12 parameters are explained in the footnote of the README.fci2 file. 2.) The output file has the following format: line1: file name line2: header, including station number, latitude, logitude, and the elevation data line3: blank line4: fields heading line5: units for the fields line6: blank line7 through line 44: data. The same fields as in the input file. *****************************************************************************/ void pams (argc, argv) int argc; char **argv; { pams_param dat[12]; FILE *fptr; void hd_pams(); char stat_key[20], filename[200]; int i=0, j, observ_num, station_num, nrec; float lat, lon, elevation; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } nrec = 0; fscanf (fptr,"%s %d %*7c %f %f %f", stat_key,&station_num,&lat,&lon,&elevation); if (strcmp(stat_key, STATION_KEY) != 0) continue; while (fscanf (fptr, "%d%f%f%f%f%f%f%f%f%f%f%f%f%hd%hd%hd%hd%hd%hd%hd%hd%hd%hd%hd%hd", &observ_num, &(dat[0].param),&(dat[1].param),&(dat[2].param),&(dat[3].param), &(dat[4].param),&(dat[5].param),&(dat[6].param),&(dat[7].param), &(dat[8].param),&(dat[9].param),&(dat[10].param),&(dat[11].param), &(dat[0].flag),&(dat[1].flag),&(dat[2].flag), &(dat[3].flag), &(dat[4].flag),&(dat[5].flag),&(dat[6].flag),&(dat[7].flag), &(dat[8].flag),&(dat[9].flag),&(dat[10].flag),&(dat[11].flag)) != EOF) { /** Commented out the following two lines if the column headings are not ** desired in the output page. **/ if (nrec % 45 == 0) (void) hd_pams (filename,stat_key,station_num,lat,lon,elevation); printf ("%4d ", ++nrec); for (j = 0; j < 12; j++) { switch (dat[j].flag) { case 0: dat[j].id = 'G'; break; case 8: /* suspected spurious data that wasn't flagged*/ dat[j].id = 'B'; break; case 7: /* equivalent to NCAR's outlier data (=2) */ dat[j].id = '?'; break; case 9: /* NCAR flag as missing or bad data */ dat[j].id = 'B'; break; case 2: /* NCAR flag as outlier (possible bad) data */ dat[j].id = '?'; break; default: printf ("ERROR: Rec. Num: %d, Flag = %hd\n", nrec, dat[j].flag); break; } } for (j = 0; j < 12; j++) /* Print the 12 variables values */ printf ("%7.2f ", dat[j].param); printf (" "); for (j = 0; j < 12; j++) printf ("%d ", dat[j].flag); /* An alternative way of printing each parameter, immediately * followed by a character indicating the dat quality can be * done as follows: for (j = 0; j < 12; j++) printf ("%.2f (%c) ", dat[j].param, dat[j].id); */ printf ("\n"); } printf ("Total records read in file %s = %d\n", filename, nrec); fclose (fptr); } } void hd_pams (filename, stat_key, stat_num, lat, lon, elevation) char *filename, *stat_key; int stat_num; float lat, lon, elevation; { int i; static char *fields[2][13] = { {"Rec #", "Press.","temp", "wbtemp", "rh", "ratio", "temp","u_wnd", "v_wnd", "avg_sp", "wnd_dir","max_sp","sol_irr"}, {" ", " (mb) ","(C) ","(C) ","(%) ","(g/kg)","(K) ","(m/s) ", " (m/s)","(m/s)","(deg)", "(m/s)", "(W/m**2)"} } ; printf ("\fFilename: %s\n", filename); printf ("Missing data value: %.2f\n", MISSING_DATA); printf ("%s %d, latitude=%.4f, longitude=%.4f, elevation=%.4f\n\n", stat_key, stat_num, lat, lon, elevation); printf ("%5s", fields[0][0]); for (i = 1; i < 13; i++) printf ("%8s", fields[0][i]); printf ("\n%5s", fields[1][0]); for (i = 1; i < 13; i++) printf ("%8s", fields[1][i]); printf ("\n\n"); } /**************************************************************************** FUNCTION: raman_lidar () PURPOSE/DESCRIPTION: Function raman_lidar reads the GSFC raman_lidar water vapor mixing ratio (wvmr) data with altitudes and times. Data is summed for one minute in the detectors and saved to a file. For the 10 minute averaged data, the data is summed for 10 minutes before the calculations are performed. Each profile has 75 meter resolution from 0.4135 to 10.299 kilometers. Zero (0) km means sea level. The site altitude is 0.229 km and the first data point is at 0.1845 km above ground level. See READEM.fci2 file for the variables and record organization. INVOCATION: (void) raman_lidar (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple pams data files. For example, raman_lidar ci2_wv911125_1m ci2_wv911126_10m will read two files: ci2_wv911125_1m, and ci2_wv911126_10m. FILE/RECORD REFERENCES: Each is named ci2_wvYYMMDD_Xm, where YY is the year, MM the month, and DD the day. X in the file name can only be either 1 or 10, indicating the 1 minute summed data or 10 minutes averaged data. EXTERNAL ROUTINES: None. NOTES: If no output is desirable, comment out the "printf" lines in the function. *****************************************************************************/ void raman_lidar (argc, argv) int argc; char **argv; { char filename[MAXPATHLEN+1], buf[250], comma; char beg_time[15], end_time[15], text[90]; int iwvmr, i=0, j, k, nprofile, itime, nalt, ialt; FILE *fptr; float rwvmr, rerr; while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr, "ERROR: Can't open file:\t %s\n", filename); continue; } fgets (buf, sizeof (buf), fptr); sscanf (buf, "%[^,]%c%s", beg_time, &comma, end_time); fgets (text, sizeof (text) - 1, fptr); fgets (buf, sizeof (buf), fptr); fgets (buf, sizeof (buf), fptr); sscanf (buf, "%d", &nprofile); printf ("%s,%s\n%s\n\n%d = # profiles\n", beg_time, end_time, text, nprofile); for (k = 0; k < nprofile; k++) { fgets (buf, sizeof (buf), fptr); sscanf (buf, "%d", &itime); /* Time of profile. */ fgets (buf, sizeof (buf), fptr); sscanf (buf, "%d", &nalt); printf ("%d = time (secs)\n%d = # alts (m)\n", itime, nalt); for (j = 0; j < nalt; j++) { if (fgets (buf, sizeof (buf), fptr) == NULL) break; sscanf (buf, "%d %g %g", &ialt, &rwvmr, &rerr); printf ("%d %g %g\n", ialt, rwvmr, rerr); } if (j != nalt) fprintf (stderr,"ERROR: Total heights specified = %d, but %d are read\n", nalt, j); } if (k != nprofile) fprintf (stderr, "ERROR? Total profiles read = %d\n", k); fclose (fptr); } } /**************************************************************************** FUNCTION: noaa_wndprfl () PURPOSE/DESCRIPTION: Function noaa_wndprfl reads NOAA windprofiles data collected during the period from Nov. 13, 1991 to Dec. 7, 1991. The original NOAA windprofiles data were stored in the Enhanced Binary Universal Form (EBUF) format. These data files were processed and provided in ASCII format by the Langley DAAC. The same data in EBUF format are available off-line. NOTE: It is assumed that the height increment on the observation station remains the same in a windprofiles record. These ASCII files range from 17 to 37 MB size. Expect to take a while to read. INVOCATION: (void) noaa_wndprfl (argc, argv); WHERE - I the number of arguments from the command line invocation. - I the argument list, including the program name and multiple pams data files. For example, noaa_wndprfl ci2_noawnd_911127_6m ci2_noawnd_911118_6m will read two files: ci2_noawnd_911127_6m, and ci2_noawnd_911118_6m FILE/RECORD REFERENCES: Each file is named ci2_noawnd_yymmdd_6m, where yy is the year, mm the month, and dd the day. A NOAA windprofiles record starts with three header lines, followed by three lines of column headings, followed by windprofile data, and ends with the parameter "Profiler in checkout mode flag" line. EXTERNAL ROUTINES: None. NOTES: If no output is desirable, comment out the "printf" lines in the function. *****************************************************************************/ void noaa_wndprfl (argc, argv) int argc; char **argv; { char filename[MAXPATHLEN+1], buf[250], keys[80], letter, *lines[10]; FILE *fptr; int i=0, j, k, recnum, year, month, day, hour, minute; float lat, lon, stat_ht, increment, height, ck_flg; float nsig_power, esig_power, vsig_power, nmean_vel; float emean_vel, vmean_vel, nvel_sigma2, evel_sigma2, vvel_sigma2; /** Open the data file **/ while (i++ < (argc-1)) { strcpy (filename, argv[i]); if ((fptr = fopen (filename, "r")) == NULL) { fprintf (stderr,"ERROR: Can't open file:\t %s\n", filename); continue; } /** HEADER lines: 1st line, date and time fields; 2nd line, statioin ** latitude and longitude fields; 3rd line, Height of station above ** sea level, and height increment fields. Next 3 lines are column ** headings. **/ for (j = 0; fgets (buf, sizeof (buf), fptr) != NULL; j = 0) { lines[j++] = strdup (buf); for (k = 0; (k < 5) && (fgets (buf, sizeof(buf), fptr) != NULL); k++) { lines[j++] = strdup (buf); } sscanf (lines[0], "%s%d%c%2d%c%2d%s%d", keys, &year, &letter, &month, &letter, &day, keys, &hour, &letter, &minute); sscanf (lines[1], "%[^:]%c%g%[^:]%c%g", keys, &letter, &lat, keys, &letter, &lon); sscanf (lines[2], "%[^:]%c%g%[^:]%c%g", keys, &letter, &stat_ht, keys, &letter, &increment); if ((lat < -90.0) || (lat > 90.0)) fprintf (stderr, "ERROR: latutude in %4d/%02d/%02d = %g\n", year, month, day, lat); if ((lon < -180.0) || (lon > 180.0)) fprintf (stderr, "ERROR: longitude in %4d/%02d/%02d = %g\n", year, month, day, lon); for (k = 0; k < j; k++) printf ("%s", lines[k]); for (recnum = 0; (recnum < MAX_NOAA) && (fgets (buf, sizeof (buf), fptr) != NULL); recnum++) { sscanf (buf, "%g %g%g%g %g%g%g %g%g%g", &height, &nsig_power, &esig_power, &vsig_power, &nmean_vel, &emean_vel, &vmean_vel, &nvel_sigma2, &evel_sigma2, &vvel_sigma2); printf ("%-8g %-8g %-8g %-8g %-8g %-8g %-8g %-8g %-8g %-8g \n", height, nsig_power, esig_power, vsig_power, nmean_vel, emean_vel, vmean_vel, nvel_sigma2, evel_sigma2, vvel_sigma2); } /* Every record ends with "Profiler in checkout mode flag". */ if (recnum == MAX_NOAA) { if (fgets (buf, sizeof (buf), fptr) != NULL) { sscanf (buf, "%[^:]%c%g", keys, &letter, &ck_flg); printf ("%-s%c %-8g\n\n", keys, letter, ck_flg); } if (fgets (buf, sizeof (buf), fptr) == NULL) break; } for (k = 0; k < j; k++) free (lines[j]); } fclose (fptr); } }