/* ui.c */
/*
* Vis5D system for visualizing five dimensional gridded data sets.
* Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul,
* Dave Santek, and Andre Battaiola.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* As a special exception to the terms of the GNU General Public
* License, you are permitted to link Vis5D with (and distribute the
* resulting source and executables) the LUI library (copyright by
* Stellar Computer Inc. and licensed for distribution with Vis5D),
* the McIDAS library, and/or the NetCDF library, where those
* libraries are governed by the terms of their own licenses.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "../config.h"
/*
* Text-based user interface for Vis5D data import program.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "analyze_i.h"
#include "file_i.h"
#include "grid_i.h"
#include "output_i.h"
#include "projlist_i.h"
#include "select_i.h"
#include "tokenize_i.h"
#include "v5d.h"
static int MaxNl;
extern char *path;
/*
* Print help information
*/
static void do_help( char *subject )
{
#define P printf
if (subject[0]==0) {
/* no subject */
P("Help is available on the following topics:\n");
P(" intro list keep omit read make visualize exit\n");
P(" info rows columns levels projection vertical\n");
P("Type 'help <topic>'\n");
}
else if (strcmp(subject,"intro")==0) {
P("Introduction:\n");
P(" This program is used for converting various formats of 3-D\n");
P("gridded data files to the v5d format used by Vis5D. In addition\n");
P("to data conversion, resampling and remapping of data is performed.\n");
P("The general approach to using this program is:\n");
P(" 1. Start the program, specifying one or more input files on\n");
P(" the command line.\n");
P(" 2. Use the list command to get a summary of the input data\n");
P(" 3. Use the keep and omit commands to select which grids to\n");
P(" put in the output file.\n");
P(" 4. Use the info command to see the parameters of the output file.\n");
P(" 5. Adjust the output file parameters with the rows, columns,\n");
P(" levels, projection, and vertical commands.\n");
P(" 6. Use the make command to generate the output file, OR ...\n");
P(" Use the visualize command to generate and visualize the output file.\n");
P(" 7. exit.\n");
P("If you only want to convert one file to v5d format without any\n");
P("resampling or remapping you would probably only do steps 1, 6 and 7.\n");
P("Currently, the following input file formats are understood:\n");
P(" McIDAS GR3D and GRID\n");
P(" Vis5D v5d and comp5d\n");
P(" EPA MM4 and RADM\n");
P(" GRADS\n");
P(" UW-AOS model VIS files\n");
}
else if (strcmp(subject,"list")==0) {
P("The list command is used to show information about the grids\n");
P("currently in memory. There are several list options:\n");
P(" list lists all the grids\n");
P(" list vars lists all variables\n");
P(" list times lists all timesteps\n");
P(" list proj lists all projections\n");
P(" list vcs lists all vertical coord systems\n");
P("List entries preceded by a * indicate that the grid will be\n");
P("included in the output file.\n");
}
else if (strcmp(subject,"keep")==0) {
P("The keep command is used to indicate which input grids should be\n");
P("included in the output file. There are many options:\n");
P(" keep all include all grids in output\n");
/*
P(" keep grid <n> include grid number n in output\n");
P(" keep grids <n> <m> include grids n through m in output\n");
*/
P(" keep var <name> include grids by variable <name>\n");
P(" keep time <yyddd> <hhmmss> include grids by the specified time\n");
P(" keep times <yyddd> <hhmmss> <yyddd> <hhmmss>\n");
P(" include grids between the given times\n");
P(" keep timestep <n> include the nth timestep\n");
P(" keep timesteps <n> <m> include the nth through mth timesteps\n");
P(" keep proj <n> keep grids projection number <n>\n");
P(" keep vcs <n> keep grids with VCS number <n>\n");
P("Use the list command to see which grids are marked as 'keep'\n");
}
else if (strcmp(subject,"omit")==0) {
P("The omit command is used to indicate which input grids should NOT\n");
P("be included in the output file. There are many options:\n");
P(" omit all omit all grids from output\n");
/*
P(" omit grid <n> omit grid number n from output\n");
P(" omit grids <n> <m> omit grids n through m from output\n");
*/
P(" omit var <name> omit grids by variable <name>\n");
P(" omit time <yyddd> <hhmmss> omit grids by the specified time\n");
P(" omit times <yyddd> <hhmmss> <yyddd> <hhmmss>\n");
P(" omit grids between the given times\n");
P(" omit timestep <n> omit the nth timestep\n");
P(" omit timesteps <n> <m> omit the nth through mth timesteps\n");
P(" omit proj <n> omit grids projection number <n>\n");
P(" omit vcs <n> omit grids with VCS number <n>\n");
P("Use the list command to see which grids are marked as 'keep'\n");
}
else if (strcmp(subject,"make")==0) {
P("The make command causes the output file to be generated. All\n");
P("grids marked as 'keep' (*) will be included in the output file.\n");
P("The input grids will be resampled and remapped to the dimensions\n");
P("and projection as reported by the 'info' command. There is one\n");
P("argument to the make command:\n");
P(" make <filename> where filename is a .v5d file.\n");
}
else if (strcmp(subject,"visualize")==0) {
P("The visualize command causes the output file to be generated and\n");
P("Vis5D to be started. All grids marked as 'keep' (*) will be included\n");
P("in the output file. The input grids will be resampled and remapped\n");
P("to the dimensions and projection as reported by the 'info' command.\n");
P("There is one optional argument to the make command:\n");
P(" visualize <filename> where filename is a .v5d file.\n");
}
else if (strcmp(subject,"exit")==0) {
P("The exit command is used to exit this program. The command quit\n");
P("does the same thing.\n");
}
else if (strcmp(subject,"read")==0) {
P("The read command is used to read another input file. The initial\n");
P("input files are specified on the command line when this program\n");
P("is started. The read command has one argument:\n");
P(" read <filename> where filename is the file to read\n");
}
else if (strcmp(subject,"info")==0) {
P("The info command shows the parameters of the output file including\n");
P("the size of the output grid, the map projection and the vertical\n");
P("coordinate system. The info command has no arguments. The\n");
P("default output file parameters are obtained from the first input\n");
P("file. The following commands are used to change the output file\n");
P("parameters:\n");
P(" rows, columns, levels, projection, vertical\n");
}
else if (strcmp(subject,"rows")==0) {
P("The rows command is used to specify how many rows are to be in\n");
P("the output file. Syntax:\n");
P(" rows <n> specify n rows in output file\n");
P("Use the 'info' command to see the current value for rows.\n");
/*
P("The map projection will be automatically adjusted to the new rows.\n");
*/
}
else if (strncmp(subject,"col",3)==0) {
P("The columns command is used to specify how may columns are to be\n");
P("in the output file. Syntax:\n");
P(" columns <n> specify n columns in output file\n");
P("Use the 'info' command to see the current value for columns.\n");
/*
P("The map projection will be automatically adjusted to the new value.\n");
*/
}
else if (strncmp(subject,"lev",3)==0) {
P("The levels command is used to specify how many levels are to be\n");
P("in the output file either for all variables or for individual\n");
P("variables. There are two syntaxes:\n");
P(" levels <n> set number of grid levels for all variables\n");
P(" levels <var> <n> set number of grid levels for one variable\n");
P("Use the 'info' command to see the current grid level values.\n");
}
else if (strncmp(subject,"proj",4)==0) {
P("The projection command is used to specify the projection of the\n");
P("output file. There are several options:\n");
P(" proj <n> Use projection number <n> (see list proj)\n");
P(" proj generic <north> <west> <rowinc> <colinc>\n");
P(" proj linear <north> <west> <rowinc> <colinc>\n");
P(" proj lambert <lat1> <lat2> <polerow> <polecol> <longitude> <colinc>\n");
P(" proj polar <centlat> <centlon> <centrow> <centcol> <colinc>\n");
}
else if (strcmp(subject,"vertical")==0) {
P("The vertical command is used to specify the vertical coordinate\n");
P("system (VCS) of the output file. There are several options:\n");
P(" vert <n> Use VCS number <n> (see list vcs)\n");
P(" vert generic <bottom> <increment>\n");
P(" vert equal <bottom> <increment>\n");
P(" vert unequal [<height 1> <height 2> ...]\n");
P(" vert pressure [<pressure 1> <pressure 2> ...]\n");
P("In the last 2 cases, if the height or pressure values are not specified\n");
P("on the command line you will be prompted to enter them one at a time.\n");
}
/* etc.. */
else {
P("Unknown command: %s\n", subject);
}
P("\n");
#undef P
}
/*
* List the grids
* Input: list - the list of grids
* what - 0 = list all grids
* 1 = list variables
* 2 = list timesteps
* 3 = list projections
* 4 = list VCSs
*/
static void do_list( struct grid_db *db, int what )
{
int i;
assert( what>=0 && what<=4 );
if (db->NumGrids==0) {
printf("No grids have been read.\n");
return;
}
switch (what) {
case 0:
/* list all grids */
print_grid_list( db );
break;
case 1:
/* list all variables */
printf("Variables:\n");
for (i=0;i<db->NumVars;i++) {
if (db->VarSelected[i]) {
printf("* ");
}
else {
printf(" ");
}
printf("%2d: %s\n", i+1, db->VarNames[i] );
}
printf("*=include variable in output file\n");
break;
case 2:
/* list all timesteps */
printf("Timesteps:\n");
for (i=0;i<db->NumTimes;i++) {
if (db->TimeSelected[i]) {
printf("* ");
}
else {
printf(" ");
}
printf("%2d: %05d %06d\n", i+1,
db->DateStamp[i], db->TimeStamp[i] );
}
printf("*=include timestep in output file\n");
break;
case 3:
/* list all projections */
printf("Map projections:\n");
print_projection_list( db );
break;
case 4:
/* list all VCSs */
printf("Vertical Coordinate Systems: (VCS)\n");
print_vcs_list( db );
break;
}
}
static void do_select_var( struct grid_db *db, char *varname, int flag )
{
int var;
char tmpvar[100];
int i;
for (var=0;var<db->NumVars;var++) {
/* tmpvar = VarNames[var] without trailing spaces */
strcpy( tmpvar, db->VarNames[var] );
i = strlen(tmpvar) - 1;
while (i>0 && tmpvar[i]==' ') {
tmpvar[i] = 0;
i--;
}
if (strcmp(tmpvar,varname)==0) {
break;
}
}
if (var==db->NumVars) {
printf("No such variable\n");
return;
}
select_variable( db, var, flag );
}
/*
* Select grids according to timestep number
* Input: list - grid list
* ts0, ts1 - range of timestep numbers (starting at 1)
* flag - 1=keep, 0=omit
*/
static void do_select_timesteps( struct grid_db *db, int ts0, int ts1,
int flag )
{
int time;
for (time=ts0;time<=ts1;time++) {
select_time( db, time-1, flag );
}
}
static void do_select_times( struct grid_db *db,
int date0, int time0,
int date1, int time1,
int flag )
{
int i;
for (i=0;i<db->NumTimes;i++) {
if ( (db->DateStamp[i]>date0
|| (db->DateStamp[i]==date0 && db->TimeStamp[i]>=time0))
&& (db->DateStamp[i]<date1
|| (db->DateStamp[i]==date1 && db->TimeStamp[i]<=time1)) ) {
select_time( db, i, flag );
}
}
}
#ifdef LEAVEOUT
/*
* Select a range of grids by number [n..m] starting at 1.
*/
static void do_select_grids( db, n, m, flag )
struct grid_db *db;
int n, m;
int flag;
{
struct grid_info *g;
int time, var;
g = nth_grid( GridList, n );
if (table_find_gridptr( Table, g, &time, &var )) {
table_mark_grid( Table, time, var, g, ALL_BITS, flag );
}
}
#endif
static int compute_maxnl( v5dstruct *v5d )
{
int i, maxnl = 0;
for (i=0;i<MAXVARS;i++) {
if (v5d->Nl[i]>maxnl) {
maxnl = v5d->Nl[i];
}
}
return maxnl;
}
static void do_read( struct grid_db *db, v5dstruct *v5dout, char *filein )
{
int oldnumgrids;
char filename[1000];
if (filein[0]==0) {
printf("No filename given!\n");
return;
}
if (filein[0] == '/' || path == NULL) {
strcpy(filename, filein);
}
else {
int len;
strcpy(filename, path);
/* add a trailing slash to path if there isn't one already */
len = strlen(filename);
if (len>0 && filename[len-1]!='/') {
strcat(filename, "/");
}
strcat(filename, filein);
}
printf("Read: %s\n", filename );
oldnumgrids = db->NumGrids;
get_file_info( filename, db );
analyze_grids( db );
select_all( db, ALL_BITS, 1 );
if (oldnumgrids==0 && db->NumGrids>0) {
/* Now we can setup defaults for the output file */
setup_defaults( db, v5dout, 1,1,1 );
MaxNl = compute_maxnl( v5dout );
}
}
/*
* Make the output file.
* Input: db - the grid database
* v5dout - describes the output file
* filename - name of output .v5d file
*/
static void do_make( struct grid_db *db, v5dstruct *v5dout, char *filein )
{
int average = 0;
int maxnl = MaxNl;
int compressmode = 1;
char filename[1000];
if (filein[0]==0) {
printf("No filename given!\n");
return;
}
if (filein[0] == '/' || path == NULL) {
strcpy(filename, filein);
}
else {
int len;
strcpy(filename, path);
/* add a trailing slash to path if there isn't one already */
len = strlen(filename);
if (len>0 && filename[len-1]!='/') {
strcat(filename, "/");
}
strcat(filename, filein);
}
printf("Making %s...\n", filename );
make_output_file( db, v5dout, filename, maxnl, average, compressmode );
printf("Done\n");
}
extern start_vis5d( char *filename );
/*
* Make the output file and start Vis5D.
* Input: db - the grid database
* v5dout - describes the output file
* name - name of output .v5d file
*/
static void do_go( struct grid_db *db, v5dstruct *v5dout, char *name )
{
int average = 0;
int maxnl = MaxNl;
int compressmode = 1;
char filein[1000], filename[1000];
if (name == NULL) {
char *user = getenv("USER");
if (user == NULL) user = "user";
strcpy(filein, user);
strcat(filein, ".v5d");
}
else {
strcpy(filein, name);
}
if (filein[0] == '/' || path == NULL) {
strcpy(filename, filein);
}
else {
int len;
strcpy(filename, path);
/* add a trailing slash to path if there isn't one already */
len = strlen(filename);
if (len>0 && filename[len-1]!='/') {
strcat(filename, "/");
}
strcat(filename, filein);
}
printf("Making %s...\n", filename );
make_output_file( db, v5dout, filename, maxnl, average, compressmode );
start_vis5d(filename);
exit(0);
}
/*
* Parse the given command and execute it.
* Input: command - the command string
* db - the grid database
* v5dout - describes the output file
*/
static void parse_command( char *command, struct grid_db *db,
v5dstruct *v5dout )
{
char **token;
int n;
/* convert command to tokens */
token = tokenize( command, &n );
if (n==0) {
free_tokens( token );
return;
}
/*
* Process the command
*/
if (strcmp(token[0],"exit")==0 || strcmp(token[0],"quit")==0) {
exit(0);
}
else if (strcmp(token[0],"help")==0) {
if (n==1) {
do_help("");
}
else {
do_help( token[1] );
}
}
else if (strcmp(token[0],"list")==0) {
if (n==1) {
do_list( db, 0 );
}
else {
if (strncmp(token[1],"var",3)==0) {
do_list( db, 1 );
}
else if (strncmp(token[1],"time",4)==0) {
do_list( db, 2 );
}
else if (strncmp(token[1],"proj",4)==0) {
do_list( db, 3 );
}
else if (strncmp(token[1],"vcs",4)==0) {
do_list( db, 4 );
}
else {
printf("Error: bad argument to list: %s\n", token[1] );
}
}
}
else if (strcmp(token[0],"rows")==0) {
/* Set number of output rows */
int nr = atoi( token[1] );
if (nr>1) {
#ifdef LEAVEOUT
/* adjust projection to match new rows */
switch (v5dout->Projection) {
case 0:
case 1: /* rectilinear*/
v5dout->ProjArgs[2] *= (float) v5dout->Nr / (float) nr;
break;
case 2: /* lambert */
v5dout->ProjArgs[2] *= (float) v5dout->Nr / (float) nr;
break;
case 3: /* polar stereographic */
v5dout->ProjArgs[2] *= (float) v5dout->Nr / (float) nr;
break;
default:
/* ??? */
;
}
#endif
v5dout->Nr = nr;
}
}
else if (strncmp(token[0],"col",3)==0) {
/* Set number of output columns */
int nc = atoi( token[1] );
if (nc>1) {
#ifdef LEAVEOUT
/* adjust projection */
switch (v5dout->Projection) {
case 0:
case 1: /* rectilinear */
v5dout->ProjArgs[3] *= (float) v5dout->Nc / (float) nc;
break;
case 2: /* lambert */
v5dout->ProjArgs[3] *= (float) v5dout->Nc / (float) nc;
v5dout->ProjArgs[5] *= (float) v5dout->Nc / (float) nc;
break;
case 3: /* polar stereographic */
v5dout->ProjArgs[3] *= (float) v5dout->Nc / (float) nc;
v5dout->ProjArgs[4] *= (float) v5dout->Nc / (float) nc;
break;
default:
/* ??? */
;
}
#endif
v5dout->Nc = nc;
}
}
else if (strncmp(token[0],"lev",3)==0) {
/* Set number of output levels */
int levels;
if (n!=2) {
printf("Error: one argument expected\n");
}
else {
levels = atoi( token[1] );
/* if (levels>1 && levels<=MAXLEVELS) { JPE: WHY > 1 */
if (levels>0 && levels<=MAXLEVELS) {
MaxNl = levels;
}
}
#ifdef LEAVEOUT
if (n==2) {
int maxnl, i;
levels = atoi( token[1] );
/* find current maxnl */
maxnl = v5dout->Nl[0];
for (i=1;i<v5dout->NumVars;i++) {
if (maxnl<v5dout->Nl[i]) maxnl = v5dout->Nl[i];
}
/* adjust vert. coord. sys. */
switch (v5dout->VerticalSystem) {
case 0:
case 1:
v5dout->VertArgs[1] *= (float) maxnl / (float) levels;
break;
case 2:
/* compute more height values */
if (levels>maxnl) {
float delta = v5dout->VertArgs[maxnl-1]
- v5dout->VertArgs[maxnl-2];
for (i=maxnl;i<levels;i++) {
v5dout->VertArgs[i] = v5dout->VertArgs[i-1] + delta;
}
}
break;
default:
/* nothing??? */
;
}
/* set number of levels for all vars */
for (i=0;i<v5dout->NumVars;i++) {
v5dout->Nl[i] = levels;
}
}
else if (n==3) {
/* number of levels for one particular variable */
levels = atoi( token[2] );
for (i=0;i<v5dout->NumVars;i++) {
if (strcmp(token[1],v5dout->VarName[i])==0) {
v5dout->Nl[i] = levels;
}
}
}
#endif
}
else if (strcmp(token[0],"info")==0) {
int i;
printf("Output file parameters:\n");
printf(" Rows: %d\n", v5dout->Nr );
printf(" Columns: %d\n", v5dout->Nc );
printf(" Max Levels: %d\n", MaxNl );
/*
for (i=0;i<v5dout->NumVars;i++) {
printf(" %-10s %d\n", v5dout->VarName[i], v5dout->Nl[i] );
}
*/
printf(" Projection: ");
switch (v5dout->Projection) {
case 0:
printf("Generic\n");
printf(" North Bound: %g\n", v5dout->ProjArgs[0] );
printf(" West Bound: %g\n", v5dout->ProjArgs[1] );
printf(" Row Increment: %g\n", v5dout->ProjArgs[2] );
printf(" Column Increment: %g\n", v5dout->ProjArgs[3] );
break;
case 1:
printf("Linear\n");
printf(" North Bound: %g deg\n", v5dout->ProjArgs[0] );
printf(" West Bound: %g deg\n", v5dout->ProjArgs[1] );
printf(" Row Increment: %g deg\n", v5dout->ProjArgs[2] );
printf(" Column Increment: %g deg\n", v5dout->ProjArgs[3] );
break;
case 2:
printf("Lambert Conformal\n");
printf(" Standard Latitude 1: %g deg\n", v5dout->ProjArgs[0] );
printf(" Standard Latitude 2: %g deg\n", v5dout->ProjArgs[1] );
printf(" North/South Pole row: %g\n", v5dout->ProjArgs[2] );
printf(" North/South Pole column: %g\n", v5dout->ProjArgs[3] );
printf(" Central Longitude: %g\n", v5dout->ProjArgs[4] );
printf(" Column increment: %g km\n", v5dout->ProjArgs[5] );
break;
case 3:
printf("Polar Stereographic\n");
printf(" Center Latitude: %g deg\n", v5dout->ProjArgs[0] );
printf(" Center Longitude: %g deg\n", v5dout->ProjArgs[1] );
printf(" Center Grid Row: %g deg\n", v5dout->ProjArgs[2] );
printf(" Center Grid Column: %g deg\n", v5dout->ProjArgs[3] );
printf(" Column increment: %g km\n", v5dout->ProjArgs[4] );
break;
default:
printf("Undefined\n");
}
printf(" Vertical Coordinate System: ");
switch (v5dout->VerticalSystem) {
case VERT_GENERIC:
printf("Generic\n");
printf(" BottomBound: %f\n", v5dout->VertArgs[0] );
printf(" LevInc: %f\n", v5dout->VertArgs[1] );
break;
case VERT_EQUAL_KM:
printf("Equally spaced km\n");
printf(" BottomBound: %f\n", v5dout->VertArgs[0] );
printf(" LevInc: %f\n", v5dout->VertArgs[1] );
break;
case VERT_UNEQUAL_KM:
printf("Unequally spaced km\n");
{
for (i=0;i<MaxNl;i++) {
printf(" Level %d: %.3f km\n", i+1, v5dout->VertArgs[i] );
}
}
break;
case VERT_UNEQUAL_MB:
printf("Unequally spaced mb\n");
{
for (i=0;i<MaxNl;i++) {
printf(" Level %d: %.3f mb\n", i+1,
height_to_pressure(v5dout->VertArgs[i]) );
}
}
break;
default:
printf("ERROR Undefined VerticalSystem: %d\n",v5dout->VerticalSystem);
}
}
else if (strcmp(token[0],"read")==0) {
/* read another input file */
if (n==2) {
do_read( db, v5dout, token[1] );
}
else {
printf("Error: missing filename argument to read command\n");
}
}
else if (strcmp(token[0],"keep")==0 || strcmp(token[0],"omit")==0) {
/* Keep/Omit Grids */
if (n>1) {
int flag;
if (strcmp(token[0],"keep")==0) {
flag = 1;
}
else {
flag = 0;
}
if (strcmp(token[1],"all")==0) {
select_all( db, ALL_BITS, flag );
}
#ifdef LEAVEOUT
else if (strncmp(token[1],"grid",4)==0) {
if (n>3) {
/* select a range */
do_select_grids( atoi(token[2]), atoi(token[3]), flag );
}
else {
/* select one */
do_select_grids( atoi(token[2]), atoi(token[2]), flag );
}
}
#endif
else if (strncmp(token[1],"var",3)==0) {
if (n<3) {
printf("Error: must specify a variable name\n");
}
else {
do_select_var( db, token[2], flag );
}
}
else if (strncmp(token[1],"timestep",8)==0) {
if (n==3) {
do_select_timesteps( db, atoi(token[2]), atoi(token[2]), flag );
}
else if (n==4) {
do_select_timesteps( db, atoi(token[2]), atoi(token[3]), flag );
}
else {
printf("Error: wrong number of arguments\n");
printf("Either: keep/omit timestep <timestep>\n");
printf(" or: keep/omit timesteps <timestep> <timestep>\n");
}
}
else if (strncmp(token[1],"time",4)==0) {
if (n==4) {
do_select_times( db, atoi(token[2]), atoi(token[3]),
atoi(token[2]), atoi(token[3]), flag );
}
else if (n==6) {
do_select_times( db, atoi(token[2]), atoi(token[3]),
atoi(token[4]), atoi(token[5]), flag );
}
else {
printf("Error: wrong number of arguments\n");
printf("Either: keep/omit time <date> <time>\n");
printf(" or: keep/omit times <date> <time> <date> <time>\n");
}
}
else if (strncmp(token[1],"proj",4)==0) {
if (n==3) {
int p = atoi(token[2])-1;
if (p<0 || p>=db->NumProj) {
printf("Error: bad projection number.\n");
}
else {
select_projection( db, p, flag );
}
}
else {
printf("Error: specify a projection number.\n");
}
}
else if (strncmp(token[1],"vcs",3)==0) {
if (n==3) {
int v = atoi(token[2])-1;
if (v<0 || v>=db->NumVcs) {
printf("Error: bad VCS number.\n");
}
else {
select_vcs( db, v, flag );
}
}
else {
printf("Error: specify a projection number\n");
}
}
else {
printf("Error: bad argument to keep/omit: %s\n", token[1] );
}
}
else {
printf("Keep/omit what? Try 'help keep' or 'help omit'\n");
}
}
else if (strcmp(token[0],"make")==0) {
if (n<2) {
printf("Error: missing filename argument to make\n");
}
else {
do_make( db, v5dout, token[1] );
}
}
else if (strcmp(token[0],"visualize")==0) {
if (n<2) {
do_go( db, v5dout, NULL );
}
else {
do_go( db, v5dout, token[1] );
}
}
else if (strncmp(token[0],"proj",4)==0) {
if (n==1) {
printf("Error: missing arguments to projection\n");
}
else if (n==2) {
int p = atoi(token[1])-1;
if (p<0 || p>=db->NumProj) {
printf("Error: bad projection number\n");
}
else {
v5dout->Projection = db->ProjList[p]->Kind;
memcpy( v5dout->ProjArgs, db->ProjList[p]->Args,
MAXPROJARGS*sizeof(float) );
}
}
else if (strcmp(token[1],"generic")==0) {
if (n<6) {
printf("Error: missing arguments to generic projection\n");
printf("Syntax: projection generic <north> <west> <rowinc> <colinc>\n");
}
else {
v5dout->Projection = 0;
v5dout->ProjArgs[0] = atof( token[2] );
v5dout->ProjArgs[1] = atof( token[3] );
v5dout->ProjArgs[2] = atof( token[4] );
v5dout->ProjArgs[3] = atof( token[5] );
}
}
else if (strcmp(token[1],"linear")==0) {
if (n<6) {
printf("Error: missing arguments to linear projection\n");
printf("Syntax: projection linear <north> <west> <rowinc> <colinc>\n");
}
else {
v5dout->Projection = 1;
v5dout->ProjArgs[0] = atof( token[2] );
v5dout->ProjArgs[1] = atof( token[3] );
v5dout->ProjArgs[2] = atof( token[4] );
v5dout->ProjArgs[3] = atof( token[5] );
}
}
else if (strcmp(token[1],"lambert")==0) {
if (n<8) {
printf("Error: missing arguments to Lambert Conformal projection\n");
printf("Syntax: projection lambert <lat1> <lat2> <polerow> <polecol> <longitude> <column-increment>\n");
}
else {
v5dout->Projection = 2;
v5dout->ProjArgs[0] = atof( token[2] );
v5dout->ProjArgs[1] = atof( token[3] );
v5dout->ProjArgs[2] = atof( token[4] );
v5dout->ProjArgs[3] = atof( token[5] );
v5dout->ProjArgs[4] = atof( token[6] );
v5dout->ProjArgs[5] = atof( token[7] );
}
}
else if (strcmp(token[1],"polar")==0) {
if (n<7) {
printf("Error: missing arguments to Polar Stereographic projection\n");
printf("Syntax: projection polar <lat> <lon> <row> <col> <column-increment>\n");
}
else {
v5dout->Projection = 3;
v5dout->ProjArgs[0] = atof( token[2] );
v5dout->ProjArgs[1] = atof( token[3] );
v5dout->ProjArgs[2] = atof( token[4] );
v5dout->ProjArgs[3] = atof( token[5] );
v5dout->ProjArgs[4] = atof( token[6] );
}
}
else {
printf("Error: bad argument to projection: %s\n", token[1] );
}
}
else if (strncmp(token[0],"vert",4)==0) {
if (n==1) {
printf("Error: missing arguments to vertical\n");
}
else if (strcmp(token[1],"generic")==0) {
if (n<4) {
printf("Error: missing arguments to generic V.C.S.\n");
printf("Syntax: vertical generic <bottom> <increment>\n");
}
else {
v5dout->VerticalSystem = 0;
v5dout->VertArgs[0] = atof( token[2] );
v5dout->VertArgs[1] = atof( token[3] );
}
}
else if (strncmp(token[1],"equal",5)==0) {
if (n<4) {
printf("Error: missing arguments to Equally-spaced KM V.C.S.\n");
printf("Syntax: vertical equal <bottom> <increment>\n");
}
else {
v5dout->VerticalSystem = 1;
v5dout->VertArgs[0] = atof( token[2] );
v5dout->VertArgs[1] = atof( token[3] );
}
}
else if (strcmp(token[1],"unequal")==0) {
v5dout->VerticalSystem = 2;
if (n==2) {
int i;
printf("Enter height values in km:\n");
for (i=0;i<MaxNl;i++) {
printf("Level %d: ", i+1);
scanf("%f", &v5dout->VertArgs[i] );
}
}
else {
int i;
for (i=2;i<n;i++) {
v5dout->VertArgs[i-2] = atof( token[i] );
}
}
}
else if (strcmp(token[1],"pressure")==0) {
v5dout->VerticalSystem = 3;
if (n==2) {
int i;
float pressure;
printf("Enter pressure values in mb:\n");
for (i=0;i<MaxNl;i++) {
printf("Level %d: ", i+1);
scanf("%f", &pressure );
v5dout->VertArgs[i] = pressure_to_height(pressure);
}
}
else {
int i;
for (i=2;i<n;i++) {
v5dout->VertArgs[i-2] = pressure_to_height(atof( token[i] ));
}
}
}
else if (n==2) {
int v = atoi(token[1])-1;
if (v<0 || v>=db->NumVcs) {
printf("Error: bad VCS number.\n");
}
else {
v5dout->VerticalSystem = db->VcsList[v]->Kind;
memcpy( v5dout->VertArgs, db->VcsList[v]->Args,
MAXVERTARGS * sizeof(float) );
}
}
else {
printf("Error: missing arguments to vertical command\n");
}
}
/* etc... */
else {
printf("Unknown command: %s\n", token[0]);
}
free_tokens( token );
}
/*
* The main loop for command-line interface:
* 1. get a command (from std input)
* 2. parse/execute command
* 3. goto 1
* Input: list - list of grids read during initialization
* v5dout - a v5dstruct which describes the output file.
*/
void ui_loop( struct grid_db *db, v5dstruct *v5dout )
{
char command[2000];
int script_mode;
/* check if reading commands from a script */
script_mode = !isatty(fileno(stdin));
select_all( db, ALL_BITS, 1 );
MaxNl = compute_maxnl( v5dout );
while (1) {
if (script_mode) {
fgets(command, 2000, stdin);
printf(">> %s\n", command );
}
else {
/* print prompt */
printf(">> ");
fflush( stdout );
/* get command string */
fgets(command, 2000, stdin);
}
if (command[0]!=0 && command[0]!='#') {
parse_command( command, db, v5dout );
}
/* this obscurity makes dbx nicer: */
command[0] = 0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1