Recipe 005
Title: Creating GrADS binary station data from ASCII
Author: B.-J. Tsuang
Created: 2008-09-04
Status: WORK IN PROGRESS
Requires:

Contents

Problem

You have an ASCII file with station data and would like to convert to a binary format that GrADS can read.

Solution

The utility stngrads, written in C++, can be useful in this regard:

 
#define VERSION "0.07"
#define RELEASE_DATE "Aug, 2001-Mar, 2007"
#define AUTHOR "Ben-Jei Tsuang"
//#define DEBUG
/*****************************************************************************
* File: stngrads.cpp
* Purpose: 
*   Covert station data to grads format
* Usage:
*   stngrads input_file output_file
* Description: 
*   1. The DSET in ctl file must and only can use %y4
*   2. One year per data file
*   3. One variable per ctl file
*   4. 
* ChangeLog:
*	0.01: 14 Mar 1999 Release by cslee
*	0.02: 28 June 1999 Release by bjtsuang
*   0.03: 7 July 1999 Release bjtsuang
*   0.04: 12 Aug 2001 Release bjtsuang
*   0.05: 9 Mar 2005 Release bjtsuangi and yylan : add U|L option
*   
*
* Sample ctl file:
* DSET   ^sample.bin
* DTYPE  station 
* STNMAP sample.map
* UNDEF  -99999.0
* TITLE  Station Data Sample
* TDEF   6 linear 12z18jan1994 1yr
* VARS 6
* ts    0  99  Surface Temperature
* us    0  99  Surface U-Wind 
* vs    0  99  Surface V-Wind 
* ps    0  99  Surface Pressure
* elev  0  99  Elevation of Station
* ds    0  99  Surface Dewpoint Temperature
* ENDVARS
*
* Sample input line format:
*  t id utme utmn var1 var2  ... 
* eg.:
*  1994 EPA008 298499 2773094 26.2 2.59 0.40 -99999 -99999 24.6
*  1994 EPA009 287181 2774582 20.7 2.09 0.30 -99999 -99999 22.1
*  1995 EPA008 298499 2773094 23.2 4.59 0.40 -99999 -99999 24.6
*  1999 EPA009 287181 2774582 10.7 6.09 0.30 -99999 -99999 22.1
*
******************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::ends;
#include <iomanip>
using std::setw;
#include <fstream>
using std:: ofstream;
using std:: ifstream;
using std:: ios;
// #include <strstream>
// using std::strstream;
/*  cpp include file
// old g++ header
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
#ifdef UNIX
#include <strstream.h>
#else
#include <strstrea.h>
#endif
*/
// c include file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>  
#include <ctype.h>
#include <math.h>
#include "station.h"
#define MAXLEN 2047 /* Maximum length of a line */
//ofstream fout("out.txt",ios::out);
int main(int argc,char *argv[])
{
	char * ofilename;
//	filebuf fb;
	ifstream fb;
	int t,told;
	float x,y;
	float val;
	char seps[]   = " ,\t\n";
	char *token;
	char *para;  //L or U
	char buf[MAXLEN+1];
	char *tstr;
	bool first=true;
	bool readFromFile=false;
	bool finish=false;
	if (2 > argc) {
		cout << "stngrads ver. " << VERSION << endl;
		cout << "copyright by " << AUTHOR << ", " << RELEASE_DATE << endl;
		cout << "Usage: stngrads ifile <ofile> [L|U]" << endl;
		cout << "Note : use '-' for standard input." << endl;
		cout << "       default output to 'a.bin' \n" << endl;
		cout << "[L|U]: L is longitude and latitude (default); U is utmE and utmN" << endl;
		cout << "./stngrads utm.txt utm.bin U" <<endl<<endl;
		cout << "Input data format:" << endl;
		cout << " time id utme(lon) utmn(lat) var1 var2  ... " << endl;
		cout << "eg.:" << endl;
		cout << "1994 EPA008 298499 2773094 26.2 2.59 0.40 -99999 -99999 24.6" << endl;
		cout << "1994 EPA009 287181 2774582 20.7 2.09 0.30 -99999 -99999 22.1" << endl;
		cout << "1995 EPA008 298499 2773094 23.2 4.59 0.40 -99999 -99999 24.6" << endl;
		cout << "1999 EPA009 287181 2774582 10.7 6.09 0.30 -99999 -99999 22.1" << endl;
		cout << ""<< endl;
		cout << "Sample ctl file:" << endl;
		cout << "DSET   ^utm.bin" << endl;
		cout << "DTYPE  station" << endl;
		cout << "STNMAP utm.map" << endl;
		cout << "UNDEF  -99999.0" << endl;
		cout << "TITLE  Station Data Sample" << endl;
		cout << "TDEF   6 linear jan1994 1yr" << endl;
		cout << "VARS 6" << endl;
		cout << "ts    0  99  Surface Temperature" << endl;
		cout << "us    0  99  Surface U-Wind" << endl;
		cout << "vs    0  99  Surface V-Wind" << endl;
		cout << "ps    0  99  Surface Pressure" << endl;
		cout << "elev  0  99  Elevation of Station" << endl;
		cout << "ds    0  99  Surface Dewpoint Temperature" << endl;
		cout << "ENDVARS" << endl << endl;
		cout << "Note :1. You may use either 1) space, 2) tab or 3) comma for seperators." << endl;
		cout << "Note :2. time must be integer and in ascending sort." << endl;
		cout << "         for example, the time of the ctl file of the above data should be:" << endl;
		cout << "         'TDEF   6 linear jan1994 1yr'" << endl;
		cout << "         The time of the first data record is the starting time. The difference" << endl;
		cout << "         between two consecutive integers is the time interval." << endl;
		exit(-1);
	}
	else {
		cout << argc<<" arguments"  << endl;
		if ('-' != argv[1][0]) {
			fb.open(argv[1],ios::in);
			readFromFile=true;
			/*
			if (fb.fail())
			{
			cout << argv[1] << " open error" << endl;
			exit(-1);
			} 
			*/
//			cin = &fb;		   // fb associated with fData
		} else {
			readFromFile=false;
		}
		if (2>=argc) {
			//	strcpy(ofilename,"a.bin") ;
			ofilename = "a.bin";
		}  // Default output file "a.bin"
		else {
			//	strcpy(ofilename,argv[2]) ;
			ofilename = argv[2];
		}
		if (3>=argc) {
			//	strcpy(ofilename,"a.bin") ;
			para="L";
			cout << "remain lonlat coordinate: " << endl;
		}  // Default output file "a.bin"
		else {
			para = argv[3];
			if ('U'==para[0]){
				cout << "convert utm to lonlat coordinate: "  << endl;
			} else cout << "remain lonlat coordinate: " << endl;
		}
	}
	data d(ofilename);
//	while(cin.getline(buf, MAXLEN, '\n'))
/*	while(
		if(readFromFile) {fb.getline(buf, MAXLEN, '\n'); }
		else {cin.getline(buf, MAXLEN, '\n')}
		)
		*/
	while(!finish)
	{
		if (readFromFile) {
			if (!fb.getline(buf, MAXLEN, '\n') ) {finish=true; continue;}
		}
		else {
			if (!cin.getline(buf, MAXLEN, '\n')) {finish=true; continue;}
		}
#ifdef DEBUG
		cout << "\nRead from input: " << buf << endl;
#endif
		token=strtok(buf,seps);      // timestamp
#ifdef DEBUG
		cout << token << endl;
#endif
		if( token != NULL) {
			t=atoi(token);      // timestamp
 
			if (first) {
				told=t;
				first=false;
			}
			if (told > t ) {
				cerr << " Time must be ascending sort." << endl;
				break;
			}
			for (; told<t; told++) {
				// terminator
				d.PTerminator();
			}
			strcpy(d.hdr.id,strtok(NULL,seps));       // Value
			x=atof(strtok(NULL,seps));       // Value
        		y=atof(strtok(NULL,seps));       // Value
			d.hdr.lon=x;       // Value
			d.hdr.lat=y;       // Value
			if ('U'==para[0]||'u'==para[0]){
#ifdef DEBUG
				cout << "\nutm coordinate: " << endl;
#endif
				UTMtoLonLat(x,y, &(d.hdr.lon),&(d.hdr.lat) );
			}
			//		print header
			d.PHeader();
			cout <<t<<"\t"<<d.hdr.id<<"\t"<<d.hdr.lon<<"\t"<<d.hdr.lat<< endl;
			//		printf( "new data\n");
			//
			token=strtok(NULL,seps);       // Value
			while( token != NULL )   {
				/* While there are tokens in "string" */
				val=atof(token);	// Value
				d.PValue(val);		
				//			printf( " %s\n", token );
				/* Get next token: */
				token = strtok( NULL, seps );
			}	
		}
	}
	return 1;
}
 
 

Discussion

See Also

No Warranty

Because the software provided in this Recipe is licensed free of charge, there is no warranty for it, to the extent permitted by applicable law. Except when otherwise stated in writing the authors and/or other parties provide the program "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the software is with you. Should the software prove defective, you assume the cost of all necessary servicing, repair or correction.

Copyright

This document has been placed in the public domain.

Last modified September 4, 2008 4:15 pm / Skin by Kevin Hughes
Powered by MediaWiki