/****************************************************************************** * * view_header.c * * Program views the header information in a datafile. * * LAST UPDATE: 2 December 1997 * * ARGUMENTS: * None. Prompts user for file name. * * FUNCTIONS CALLED: * read_hdr Reads 1000-byte header * * ORIGINAL AUTHOR: * Don Anderson, CIRES/CDC, November 1997 * * NOTES: * (1) Assumes data are in standard CDC Climate Satellite Group data format, * including 1000 bytes of header information. * ******************************************************************************/ #include #include #include #include /** Define structures **/ struct units_text { char text[40] ; /* Description of data field */ } ; struct describe_text { char text[80] ; /* Description of data field */ } ; struct std_hdr { char filename[80] ; /* Name of file */ char satellite[20] ; /* Name of satellite */ char sensor[20] ; /* Name of sensor */ short satid ; /* Satellite ID */ short fields ; /* Number of (lo-res) fields */ short pixperscan ; /* Pixels per (lo-res) scanline */ short hifields ; /* Number of hi-res fields */ short hipixperscan ; /* Number of hi-res pixels per scan */ short missing_val ; /* Value for missing data */ float *scale ; /* Scaling factor for each field */ float *offset ; /* Offset value for each field */ struct units_text *units ; /* Units for each field */ struct describe_text *description ; /* Description for each field */ } ; /** Function prototypes **/ int read_hdr ( FILE *, struct std_hdr * ) ; /** Main program **/ void main ( argc, argv ) int argc ; char **argv ; { int error_flag ; /* Error flag */ int i, j ; /* Generic counters */ FILE *infile ; /* Pointer to input file */ char infile_str[160] ; /* Name of input file */ short mis_val = -9999 ; /* Missing value */ int returnval ; /* Value returned from function call */ struct std_hdr hdr ; /* Header data */ int reclen ; /* Record length */ long itime ; /* time in seconds from 1/1/70 */ long ltime ; /* last scan time */ char date_str[9] ; /* Date string (MM-DD-YY) */ char time_str[9] ; /* Time string (HH:MM:SS) */ int nscan=0 ; /* Number of scans counter */ int tscan=0 ; /* Total number of scans */ int nfiles=0 ; /* Number of input files */ char buf[5000] ; /* dummy array to read to EOR */ error_flag = 0 ; /** Get name of input file **/ if ( argc > 1) strcpy ( infile_str, argv[1] ); else { printf ( "\n Enter the input file name: " ) ; gets ( infile_str ) ; if ( infile_str[0] == '\0' ) exit (1) ; } while ( ( infile = fopen ( infile_str, "r" ) ) == NULL ) { printf (" Unable to open input file, please try again!\n") ; printf (" Please enter the input file name: ") ; gets ( infile_str ) ; } /** Read and echo the header data **/ while ( ( returnval = read_hdr ( infile, &hdr ) ) == 0 ) { nscan = 0; if ( returnval < 0 ) { printf ( " Error %d reading header -- exiting program\n", returnval ) ; exit (1) ; } nfiles = nfiles + 1 ; if ( nfiles == 1 ) { printf ( "\n Datafile name: %60s\n", hdr.filename ) ; printf ( " Satellite: %20s\n", hdr.satellite ) ; printf ( " Sensor: %20s\n\n", hdr.sensor ) ; if (hdr.hifields > 0) { printf (" Satellite ID: %5d\n", hdr.satid); printf (" Missing value: %5d\n", hdr.missing_val); printf (" Number of low-resolution fields: %5d\n", hdr.fields); printf (" Number of pixels per low-res scan: %5d\n", hdr.pixperscan); printf (" Number of hi-resolution fields: %5d\n", hdr.hifields); printf (" Number of pixels per high-res scan: %5d\n\n",hdr.hipixperscan); } else { printf (" Satellite ID: %5d\n", hdr.satid); printf (" Missing value: %5d\n", hdr.missing_val ) ; printf (" Number of fields: %5d\n", hdr.fields ) ; printf (" Number of pixels per scan: %5d\n\n", hdr.pixperscan ) ; } if ( hdr.hifields > 0 ) { printf ( " Var Res Scale Offset Units Description\n" ) ; printf ( " --- --- ----- ------ ----- -----------\n" ) ; } else { printf ( " Var Scale Offset Units Description\n" ) ; printf ( " --- ----- ------ ----- -----------\n" ) ; } for ( i=0; i < hdr.fields ; i++) if ( hdr.hifields > 0 ) printf ( " %3d LOW %9.2f %9.2f %8s %40s\n", i+1, hdr.scale[i], hdr.offset[i], &hdr.units[i], &hdr.description[i] ) ; else printf ( " %3d %9.2f %9.2f %8s %40s\n", i+1, hdr.scale[i], hdr.offset[i], &hdr.units[i], &hdr.description[i] ) ; for ( j=i; j < hdr.fields + hdr.hifields ; j++) printf ( " %3d HIGH %9.2f %9.2f %8s %40s\n", j+1, hdr.scale[j], hdr.offset[j], &hdr.units[j], &hdr.description[j] ) ; printf ( "\n" ) ; } /** Read through file to determine the number of records **/ reclen = ( hdr.fields + hdr.hifields + 4 ) * 2 * hdr.pixperscan + ( hdr.hifields + 4 ) * 2 * ( hdr.hipixperscan / 2 ) + ( hdr.hifields + 4 ) * 2 * hdr.hipixperscan ; while ( fread ( &itime, 4, 1, infile ) ) { if ( itime == hdr.missing_val ) { date ( date_str, time_str, ltime, 70 ) ; printf (" File %2d end time: %8s %8s\n",nfiles, date_str, time_str); fread ( &buf, reclen - 4, 1, infile ) ; break ; } if ( nscan == 0 ) { date ( date_str, time_str, itime, 70 ) ; printf ("\n File %2d start time: %8s %8s\n",nfiles, date_str, time_str); } fread ( &buf, reclen - 4, 1, infile ) ; nscan = nscan + 1 ; tscan = tscan + 1 ; ltime = itime ; } } printf ( " File contains %6d scan lines!\n", tscan ) ; printf ( " File contains %6d input files!\n", nfiles ) ; /** Clean up and exit **/ outta_here : if ( infile != NULL ) fclose ( infile ) ; if ( error_flag < 0 ) printf ( "Error %d\n", error_flag ) ; return ; } /****************************************************************************** * * read_hdr * * Fills the passed std_hdr header structure with header data * read from the specified file. * * LAST UPDATE: 26 November 1997 * * ARGUMENTS: * * Name Type Description * ---- ---- ----------- * infile *FILE Opened input data file pointer * hdr *struct std_hdr Pointer to std_hdr structure * * ORIGINAL AUTHORS: * Don Anderson and Wesley Berg, CIRES/CDC, November 1997 * * RETURNS: 0 If successful * -1 If error allocating space * -2 If error returned from fread * * NOTES: * (1) The passed file descriptor ("infile") must be for a file which * has already been opened * (2) Binary read (fread) stops at the 1000th byte of the file * (end of header) * (3) Example of use: * To print the 0th field description from the calling routine, * printf ("Description of field 0 is %s\n", hdrstruct.description[0]); * ***************************************************************************/ int read_hdr ( FILE *infile, struct std_hdr *hdr ) { char buff[5000] ; /* Buffer for filler bytes */ int error_flag ; /* Error flag */ short fields ; /* Number of fields */ int i,n ; /* Generic counters */ error_flag = 0 ; if ((n=fread ( hdr->filename, 1, 80, infile )) != 80) { error_flag = -2 ; goto outta_here ; } fread ( hdr->satellite, 1, 20, infile ) ; fread ( hdr->sensor, 1, 20, infile ) ; fread ( &hdr->satid, 2, 1, infile ) ; fread ( &hdr->fields, 2, 1, infile ) ; fread ( &hdr->pixperscan, 2, 1, infile ) ; fread ( &hdr->hifields, 2, 1, infile ) ; fread ( &hdr->hipixperscan, 2, 1, infile ) ; fread ( &hdr->missing_val, 2, 1, infile ) ; fields = hdr->fields + hdr->hifields ; /** Allocate space for variable-length records **/ hdr->scale = ( float * ) malloc ( ( hdr->fields + hdr->hifields ) * sizeof ( float ) ) ; hdr->offset = ( float * ) malloc ( ( hdr->fields + hdr->hifields ) * sizeof ( float ) ) ; hdr->units = ( struct units_text * ) malloc ( ( hdr->fields + hdr->hifields ) * sizeof ( struct units_text ) ) ; hdr->description = ( struct describe_text * ) malloc ( ( hdr->fields + hdr->hifields ) * sizeof ( struct describe_text ) ) ; if ( hdr->scale == NULL || hdr->offset == NULL || hdr->units == NULL || hdr->description == NULL ) { error_flag = -1 ; goto outta_here ; } for ( i = 0 ; i < ( hdr->fields + hdr->hifields ) ; i++ ) { fread ( &hdr->scale[i], 4, 1, infile ) ; fread ( &hdr->offset[i], 4, 1, infile ) ; fread ( &hdr->units[i], 40, 1, infile ) ; fread ( &hdr->description[i], 80, 1, infile ) ; } /** Read past additional bytes to get to 5000 **/ if ( ! fread ( buff, 5000 - 132 - ( fields * 128 ), 1, infile ) ) error_flag = -2 ; outta_here : return ( error_flag ) ; } /**************************************************************************** * * date * * Converts integer time in seconds from specified year into a date and time * string * * ARGUMENTS: * Name Type Description * ---- ---- ----------- * *date_str char Date string (MM-DD-YY) * *time_str char Time string (HH:MM:SS) * itime long integer time in seconds from base_year * base_year int Baseline year (i.e 70 -> time from 1970) * *****************************************************************************/ date (char *date_str, char *time_str, long itime, int base_year) { long itime2; int mon,day,yr,tday,i,ndays=365,ind; int hr,min,sec; static int julian[2][12] = { {1,32,60,91,121,152,182,213,244,274,305,335}, {1,32,61,92,122,153,183,214,245,275,306,336}}; yr = base_year ; itime2 = itime ; while ((itime2 - ndays*86400) > 0) { yr = yr + 1; itime2 = itime2 - ndays*86400; if (yr%4 == 0) ndays = 366; else ndays = 365; } if (yr%4 == 0) ind = 1; else ind = 0; mon = 12; tday = itime2/86400; for (i=1; i<=12; i++) { if (julian[ind][i-1] > tday+1) { mon = i-1; break; } } day = tday - julian[ind][mon-1] + 2; itime2 = itime2 - (julian[ind][mon-1]+day-2)*86400; hr = itime2/3600; itime2 = itime2 - hr*3600; min = itime2/60; itime2 = itime2 - min*60; sec = itime2; date_str[0] = '0' + (mon/10); date_str[1] = '0' + (mon%10); date_str[2] = '-'; date_str[3] = '0' + (day/10); date_str[4] = '0' + (day%10); date_str[5] = '-'; date_str[6] = '0' + (yr/10); date_str[7] = '0' + (yr%10); date_str[8] = '\0'; time_str[0] = '0' + (hr/10); time_str[1] = '0' + (hr%10); time_str[2] = ':'; time_str[3] = '0' + (min/10); time_str[4] = '0' + (min%10); time_str[5] = ':'; time_str[6] = '0' + (sec/10); time_str[7] = '0' + (sec%10); time_str[8] = '\0'; return(1); }