/* read_gr3d.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"
/*
* Functions for reading McIDAS GR3D files
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "binio.h"
#include "file_i.h"
#include "grid_i.h"
#include "misc_i.h"
#include "proj_i.h"
#include "projlist_i.h"
#include "v5d.h"
/*
* Scan the named file, createing a grid_info struct for each grid. Store
* the grid_info structs in the grid data base.
* Input: name - name of McIDAS GR3D file.
* db - the grid data base
* Return: number of grids found in the file
*/
int get_gr3d_info( char *name, struct grid_db *db )
{
struct grid_info *info;
int f;
int i, numgrids, firstgridpos;
int header[64];
int grids = 0;
float args[20];
/* Open the file */
f = open( name, O_RDONLY );
if (f<0) {
return 0;
}
/* Read the file header (64 4-byte words) */
read_int4_array( f, header, 64 );
/* Determine how many 3-D grids are in the file */
numgrids = header[11];
firstgridpos = header[12];
/* Read the description of each 3-D grid */
for (i=0;i<numgrids;i++) {
int mapproj, vertsys;
if (lseek( f, 256 + i*256, SEEK_SET ) < 0) {
/* error */
continue;
}
read_int4_array( f, header, 64 );
/* If the grid size is valid */
if ( header[1]>=2 && header[1]<=MAXROWS
&& header[2]>=2 && header[2]<=MAXCOLUMNS
&& header[3]>=2 && header[3]<=MAXLEVELS) {
info = alloc_grid_info();
info->FileName = strdup( name );
info->Format = FILE_GR3D;
info->Position = header[4]*4; /* offset to start of data, in bytes */
info->Nr = header[1];
info->Nc = header[2];
info->Nl = header[3];
info->DateStamp = header[5]; /* Date in YYDDD format */
info->TimeStamp = header[6]; /* Time in HHMMSS format */
{ /* Get variable name, remove trailing spaces */
char varname[10];
int j;
/* Do this instead of memcpy because it works on Crays */
varname[0] = (char) ((header[8] >> 24) & 0xff);
varname[1] = (char) ((header[8] >> 16) & 0xff);
varname[2] = (char) ((header[8] >> 8) & 0xff);
varname[3] = (char) ( header[8] & 0xff);
varname[4] = 0;
for (j=3;j>=0 && varname[j]==' ';j--) {
varname[j] = 0;
}
info->VarName = strdup( varname );
}
mapproj = header[21];
if (mapproj==4) {
/* Rectilinear lat/lon */
args[0] = (float) header[22] / 10000.0; /* North Lat */
args[1] = (float) header[23] / 10000.0; /* West Lon */
args[2] = (float) header[24] / 10000.0; /* Lat Inc */
args[3] = (float) header[25] / 10000.0; /* Lon Inc */
info->Proj = new_projection( db, PROJ_LINEAR, info->Nr, info->Nc,
args );
}
else {
/* other map projections not implemented */
}
vertsys = header[30]; /* vertical coord system */
if (vertsys==1) {
float top = (float) header[31] / 1000.0; /* Top in km */
float inc = (float) header[32] / 1000.0; /* Level increment */
args[0] = top - inc * (info->Nl-1);
args[1] = inc;
info->Vcs = new_vcs( db, VERT_EQUAL_KM, info->Nl, 0, args );
}
else {
/* other vertical coord systems */
}
append_grid( info, db );
grids++;
}
}
return grids;
}
/*
* Get the grid data described by g.
* Input: g - pointer to a grid_info structure. It tells us which grid
* in which file is needed.
* Return: pointer to grid data (can be free()'d when finished)
* OR return NULL if there's an error.
*/
float *get_gr3d_data( struct grid_info *g )
{
float *data;
int f, count, read;
/* open file, seek to grid position */
f = open( g->FileName, O_RDONLY );
if (f<0) return NULL;
if (lseek( f, g->Position, SEEK_SET ) != g->Position) {
/* seek failed */
printf("Error: seek grid data from %s failed\n", g->FileName );
close(f);
return NULL;
}
/* allocate buffer */
count = g->Nr * g->Nc * g->Nl;
data = (float *) malloc( count * sizeof(float) );
if (!data) {
printf("Error: out of memory in get_gr3d_data\n");
return NULL;
}
read = read_float4_array( f, data, count );
if (read<count) {
printf("Error: read grid data from %s failed\n", g->FileName );
free( data );
close(f);
return NULL;
}
/* print_min_max( data, count );*/
close(f);
return data;
}
syntax highlighted by Code2HTML, v. 0.9.1