/********************************************************************** * PROGRAM DESCRIPTION : Convert OLD URSI format to NEW URSI format * "NEW" = ursi international exchange format * "OLD" = WDC/A archive format * INPUT : PC disk file with names of OLD URSI files to combine into 1 * NEW URSI file (OLD URSI names in order) * Each file named contains 80 byte records terminated with CR/LF. * OUTPUT: PC disk file named SSSYY.NEW where SSS is station code and * YY is year * USAGE : old2new file-of-filenames * FUNCTION : converts old URSI data files to a single file of new URSI data * AUTHOR : Chris Wells * DATE : December 07, 1988 * MODIFIED : November 2, 1989 - port to PC; input from file of filenames * PROGRAM LOGIC : * COMMENTS : 1 old URSI file = 1 month, all parameters * 1 new URSI file = 1 year, all parameters * 1 block = 1 month, 1 parameter * UPDATES : 3/29/89 use 5-character station code read from file * 4/24/89 EBCDIC; copy all input tape files, changing output * files upon finding a new year or new station code * 5/12/89 log file for screen output; file numbers on output * 4/11/91 enhance log file output for debugging bad input; * open log file in append mode; add verbose flag; * 9/24/91 correct leap year determination in Ndays; * re-initialize entire month of data to blanks to * correct problem encountered when some input files * have missing days (instead of blank-filled) * 10/16/91 (TAW) read header info from OU_HEADE.OK file * 10/17/91 (TAW) no blanks in parameter type * 7/15/92 (TAW) leap year correction **********************************************************************/ #include #include #include #include #define NEW_RECORD_SIZE 120 #define OLD_RECORD_SIZE 80 #define OKFILE "OU_HEADE.OK" struct PARAMETER { char value[5]; }; struct OLD_URSI_Header { char stationcode[5], year[2], month[2], stationname[16], country[15], timezone[5]; float latitude, longitude; } Header; struct OLD_URSI_Parameter_Month { char year[2], month[2]; int daysinmonth; char parametertype[2]; struct PARAMETER monthdata[31][24], summary[7][24]; } MonthData; int FilesWritten; static char InputPath[32], OutputPath[32]; FILE *flog, *oldtape, *newtape; int Verbose; char UtilStr[81]; int Read_OLD_URSI_Record( FILE **oldtape, char record[OLD_RECORD_SIZE] ); void HeaderRecord(char stacode[],char year[],char month[], struct OLD_URSI_Header *header); void Error_Exit( char errstring[] ); int Write_NEW_URSI_Block( FILE **newtape, struct OLD_URSI_Header header, struct OLD_URSI_Parameter_Month month ); void Process_OLD_URSI_Record( char Record[OLD_RECORD_SIZE], struct OLD_URSI_Parameter_Month *Month ); void Initialize_OLD_Month( struct OLD_URSI_Parameter_Month *Month ); void main( int argc, char *argv[] ) { static char OldRecord[OLD_RECORD_SIZE], lastchar[2], lastyr[2], lastSC[5], message[60]; static char logname[32], drive[32],dir[32],fname[32],ext[32]; int FileIn; FILE *fp; char stacode[4]; char year[3],month[3]; /*** get the command line parameters ***/ if ( argc < 2 ) { printf(" USAGE: olds2new file-of-filenames [VERBOSE]\n"); exit(1); } Verbose = ( argc >= 3 ) ? 1 : 0; if ( Verbose ) printf("VERBOSE mode set\n"); _splitpath( argv[1],drive,dir,fname,ext ); sprintf( logname,"%s.LOG",fname ); if ( (flog = fopen( logname,"a" ) ) == NULL ) Error_Exit( "can't open LOG file" ); FileIn = 0; /*******************************************************/ /* loop over all input files in file on command line */ /*******************************************************/ fp = fopen( argv[1],"r" ); while ( fgets(InputPath,32,fp) ) { /*** open an OLD URSI input file ***/ InputPath[strlen(InputPath)-1] = 0; /* remove LF terminator */ if ( (oldtape = fopen(InputPath,"r") ) == NULL ) { sprintf( message,"OPENING INPUT FILE %s",InputPath ); Error_Exit( message ); } /*** if first input file, open output file ***/ if ( ! FileIn ) { /*** read OLD URSI header record to form output file name ***/ if ( ! Read_OLD_URSI_Record( &oldtape,OldRecord ) ) { sprintf( message,"FIRST FILE IS EMPTY : %s",InputPath ); Error_Exit( message ); } sprintf( OutputPath,"%5.5s.NEW",&OldRecord[2] ); if ( (newtape = fopen(OutputPath,"w") ) == NULL ) Error_Exit( "OPENING OUTPUT FILE" ); rewind( oldtape ); /*** set flags to nothing ***/ strncpy( lastyr,"-1",2 ); strncpy( lastSC,"-1-1-",5 ); } Initialize_OLD_Month( &MonthData ); /*** read in the OLD URSI header record ***/ if ( ! Read_OLD_URSI_Record( &oldtape,OldRecord ) ) { sprintf( message,"EMPTY OLD URSI INPUT FILE %s",InputPath ); Error_Exit( message ); } /*** decode 3-letter station code, year, month from first record ***/ strncpy( stacode,OldRecord+2,3 ); stacode[3]='\0'; strncpy( year,OldRecord+5,2 ); year[2]='\0'; strncpy( month,OldRecord+7,2 ); month[2]='\0'; HeaderRecord( stacode,year,month,&Header ); /*** if year changed or station code changed, BALK ***/ if ( (strncmp(Header.year,lastyr,2) && strncmp(lastyr,"-1",2) ) || (strncmp(Header.stationcode,lastSC,5) && strncmp(lastSC,"-1-1-",5) ) ) { printf("%s %2.2s\n","Year = ",Header.year); printf("%s %5.5s\n","Station code =",Header.stationcode); sprintf( message,"CHANGE OF YEAR OR STATION CODE in file %s",InputPath ); Error_Exit( message ); } strncpy( lastyr,Header.year,2 ); strncpy( lastSC,Header.stationcode,5 ); printf("%03d: %56.56s\n",FileIn,OldRecord ); fprintf( flog,"%03d: %56.56s\n",FileIn++,OldRecord ); if ( Verbose ) fflush( flog ); strncpy( lastchar,"-1",2 ); /*** read in all OLD URSI data from input file ***/ while ( Read_OLD_URSI_Record(&oldtape,OldRecord) ) { /*** skip over the OLD URSI record separator ***/ if ( strncmp(&OldRecord[0],"1 ",2) == 0 ) continue; /*** skip over the OLD URSI end-of-file flag ***/ if ( strncmp(&OldRecord[0]," ",2) == 0 ) continue; /*** check if a new characteristic was read ***/ if ( strncmp(lastchar,&OldRecord[11],2) ) { if ( strncmp(lastchar,"-1",2) ) Write_NEW_URSI_Block( &newtape,Header,MonthData ); strncpy( lastchar,&OldRecord[11],2 ); /*....................................................* * 9/24/91: re-initialize entire month of data to * compensate for some input files not having * blank-filled records for some days (instead * those days just aren't there) *.....................................................*/ Initialize_OLD_Month( &MonthData ); } Process_OLD_URSI_Record( OldRecord,&MonthData ); } /*** end of OLD URSI input file ***/ Write_NEW_URSI_Block( &newtape,Header,MonthData ); fclose(oldtape); } printf( "=============================================================\n"); fprintf(flog,"=============================================================\n" ); printf( "... NEW URSI OUTPUT FILE IS %s\n",OutputPath ); fprintf( flog,"... NEW URSI OUTPUT FILE IS %s\n",OutputPath ); fclose( flog ); fclose( newtape ); exit( 0 ); } /********************************************************************** * read a logical record from the OLD URSI tape * * arguments : * * record : the logical record read * **********************************************************************/ int Read_OLD_URSI_Record( FILE **oldtape, char record[OLD_RECORD_SIZE] ) { static char Buffer[OLD_RECORD_SIZE+2]; /* +2 for CR/LF */ if ( ! fgets( Buffer,OLD_RECORD_SIZE+2,*oldtape ) ) return( 0 ); if ( strlen(Buffer) == 1 ) /*** allow for blank last line ***/ return( 0 ); strncpy( record,Buffer,OLD_RECORD_SIZE ); /*** (TAW 10/17/91) no blanks in parameter type ***/ if( ! strncmp(&record[11]," ",2) ) strncpy( &record[11],"00",2 ); if( ! strncmp(&record[11]," ",1) ) strncpy( &record[11],"0",1 ); return( 1 ); } /******************************************************************** * 10/16/91 (TAW) * Get header info. from the OU_HEADE.OK file ********************************************************************/ void HeaderRecord(char stacode[],char year[],char month[], struct OLD_URSI_Header *header) { int found; char temp[5]; float val; static char Buffer[93]; int yr,mn; int begyrt,begmnt; int endyrt,endmnt; FILE *OU_File; strncpy( temp,year,2 ); temp[2] = '\0'; yr = atoi( temp ); strncpy( temp,month,2 ); temp[2] = '\0'; mn = atoi( temp ); if( (OU_File = fopen( OKFILE,"r" )) == NULL ) { sprintf(UtilStr,"%s %s","UNABLE to open",OKFILE); Error_Exit(UtilStr); return; } while( fgets( Buffer,94,OU_File ) ) { found = 0; if( ! strncmp( Buffer+2,stacode,3 ) ) { found = 1; if( strncmp( Buffer+80," ",2 ) != 0 ) { found = 0; strncpy( temp,Buffer+80,2 ); temp[2] = '\0'; begyrt = atoi( temp ); strncpy( temp,Buffer+82,2 ); temp[2] = '\0'; begmnt = atoi( temp ); } else { begyrt = -1; begmnt = 1; } if( strncmp( Buffer+84," ",2 ) != 0 ) { found = 0; strncpy( temp,Buffer+84,2 ); temp[2] = '\0'; endyrt = atoi( temp ); strncpy( temp,Buffer+86,2 ); temp[2] = '\0'; endmnt = atoi( temp ); } else { endyrt = 9999; endmnt = 12; } if( ! found ) { if( (yr > begyrt) && (yr < endyrt) ) { found = 1; } else if( (yr == endyrt) && (mn <= endmnt) ) { found = 1; } else if( (yr == begyrt) && (mn >= begmnt) ) { found = 1; } } if( found ) { strncpy( header->stationcode,Buffer+75,5 ); strncpy( header->year,year,2 ); strncpy( header->month,month,2 ); strncpy( header->stationname,Buffer+13,15 ); strncpy( header->country,Buffer+29,15 ); strncpy( header->timezone,Buffer+69,5 ); strncpy( temp,Buffer+47,3 ); temp[3] = (char) 0; val = ((float) atoi( temp )) / 10.0; if ( ! strncmp( Buffer+50,"S",1 ) ) val = (float)-1.0 * val; header->latitude = val; strncpy( temp,Buffer+51,4 ); temp[4] = (char) 0; val = ((float) atoi( temp )) / 10.0; if ( ! strncmp( Buffer+55,"W",1 ) ) val = val * -1.0; header->longitude = val; break; } } } if( !found ) { sprintf(UtilStr,"%s %s","UNABLE to find data in",OKFILE); Error_Exit(UtilStr); } fclose(OU_File); return; } /********************************************************************* * abort the program after giving an error message * *********************************************************************/ void Error_Exit( char errstring[] ) { printf(" ERROR : %s\n",errstring); fprintf( flog," ERROR : %s\n",errstring ); fclose( flog ); exit(1); } /********************************************************************* * compute the number of days in this month * * arguments : * * month : month string like "03" * * year : year string like "87" * *********************************************************************/ int Ndays( char month[],char year[2] ) { int yr,mon; char temp[3]; strncpy( temp,year,2 ); temp[3] = 0; yr = atoi( temp ) + 1900; strncpy( temp,month,2 ); temp[3] = 0; mon = atoi( temp ); if ( (mon==9)||(mon==4)||(mon==6)||(mon==11) ) return( 30 ); if ( mon==2 ) { /* 7/15/92: correct leap year determination */ if ( ( (yr%4)==0 ) && ( (yr%100)!=0 ) || ( (yr%400)==0 ) ) return( 29 ); else return( 28 ); } return( 31 ); } /*********************************************************************** * write a block of new ursi data to tape * * arguments : * * newtape : file handle of new tape * * header : old ursi processed header * * month : old ursi data month * ***********************************************************************/ int Write_NEW_URSI_Block( FILE **newtape, struct OLD_URSI_Header header, struct OLD_URSI_Parameter_Month month ) { static char NewBlock[NEW_RECORD_SIZE+1], temp[5]; int pos,val,i,hr; float rval; strncpy( &NewBlock[0],header.stationname,15 ); NewBlock[15] = ' '; NewBlock[16] = NewBlock[17] = NewBlock[18] = NewBlock[19] = ' '; strncpy( &NewBlock[20],header.stationcode,5 ); strncpy( temp,header.timezone,4 ); temp[4] = '\0'; val = atoi( temp ) / 10; sprintf( temp,"%03d%c",val,header.timezone[4] ); strncpy( &NewBlock[25],temp,4 ); rval = (float)90.0 - header.latitude; val = (int) (rval * (float)10.0); sprintf( &NewBlock[29],"%04d",val ); if ( header.longitude < 0 ) sprintf( &NewBlock[33],"%04d",(int)((360.0+header.longitude)*10) ); else sprintf( &NewBlock[33],"%04d",(int)(header.longitude*10) ); NewBlock[37] = '1'; NewBlock[38] = '9'; NewBlock[39] = header.year[0]; NewBlock[40] = header.year[1]; strncpy( &NewBlock[41],header.month,2 ); strncpy( &NewBlock[43],month.parametertype,2 ); for ( i = 45; i < 120; i++ ) NewBlock[i] = ' '; NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( i = 0; i < month.daysinmonth; i++ ) { for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.monthdata[i][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); } for ( i = month.daysinmonth; i < 31; i++ ) { for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos]," ",5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); } for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[0][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[1][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[2][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[3][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[5][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[4][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos],month.summary[6][hr].value,5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); for ( pos = 0, hr = 0; hr < 24; hr++, pos += 5 ) strncpy( &NewBlock[pos]," ",5 ); NewBlock[120] = 0; fprintf( *newtape,"%s\n",NewBlock ); return( 1 ); } /*********************************************************************** * process an OLD URSI logical record * * arguments : * * Record : the record to process * * Month : the cumulative OLD URSI month of data * ***********************************************************************/ void Process_OLD_URSI_Record( char Record[OLD_RECORD_SIZE], struct OLD_URSI_Parameter_Month *Month ) { char temp[6]; int i, indx, day, hourst, startpos; strncpy( Month->year,&Record[5],2 ); strncpy( Month->month,&Record[7],2 ); Month->daysinmonth = Ndays( Month->month,Month->year ); strncpy( Month->parametertype,&Record[11],2 ); if ( Record[1] == '1' ) hourst = 0; else hourst = 12; startpos = 13; /*** hourly measurement record ***/ if ( Record[0] == '1' ) { strncpy( temp,&Record[9],2 ); temp[2] = 0; day = atoi( temp ); if ( Verbose ) { fprintf( flog,"DATE:%2.2s%2.2s%02d %2.2s\n",Month->year, Month->month,day,Record+11 ); fflush( flog ); } for ( i = hourst; i < hourst+12; i++, startpos += 5 ) strncpy( Month->monthdata[day-1][i].value,&Record[startpos],5 ); } /*** monthly summary record ***/ else { indx = -1; if ( ! strncmp(&Record[9],"40",2) ) indx = 0; if ( ! strncmp(&Record[9],"50",2) ) indx = 1; if ( ! strncmp(&Record[9],"60",2) ) indx = 2; if ( ! strncmp(&Record[9],"70",2) ) indx = 3; if ( ! strncmp(&Record[9],"80",2) ) indx = 4; if ( ! strncmp(&Record[9],"77",2) ) indx = 5; if ( ! strncmp(&Record[9],"87",2) ) indx = 6; if ( Verbose ) { fprintf( flog,"SUMMARY:%2.2s\n",Record+9 ); fflush( flog ); } for ( i = hourst; i < hourst+12; i++, startpos += 5 ) strncpy( Month->summary[indx][i].value,&Record[startpos],5 ); } return; } /*********************************************************************** * initialize the OLD URSI month of data to all blanks for safety * * arguments : * * Month : OLD URSI parameter month * ***********************************************************************/ void Initialize_OLD_Month( struct OLD_URSI_Parameter_Month *Month ) { int hour, day, summ; strncpy( Month->year," ",2 ); strncpy( Month->month," ",2 ); Month->daysinmonth = 0; strncpy( Month->parametertype," ",2 ); for ( hour = 0; hour < 24; hour++ ) { for ( day = 0; day < 31; day++ ) strncpy( Month->monthdata[day][hour].value," ",5 ); for ( summ = 0; summ < 7; summ++ ) strncpy( Month->summary[summ][hour].value," ",5 ); } return; } /* int strupr( string ) char string[]; { int i; for ( i = 0; i < strlen(string); i++ ) string[i] = toupper(string[i] ); return; } */