/* * 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" /* read_epa.c */ /* * Functions for working with EPA files */ #include #include #include #include #include #include "file_i.h" #include "grid_i.h" #include "misc_i.h" #include "model_i.h" #include "proj_i.h" #include "projlist_i.h" #include "v5d.h" #ifdef EPA #define LATLON_FILE "latlon.dat" /* This is needed by mm4.c: */ float mm4Sigma[MAXLEVELS]; int model_type; /* Sigma value for each level in the 3-D grid for 15 level RADM files (how general?) */ static float RadmSigma15[15] = { 0.995, 0.985, 0.970, 0.945, 0.910, 0.865, 0.810, 0.740, 0.650, 0.550, 0.450, 0.350, 0.250, 0.150, 0.050 }; /* Sigma value for each level in the 3-D grid for 6 level RADM files (how general?) */ static float RadmSigma6[6] = { 0.99, 0.955, 0.885, 0.720, 0.450, 0.150, }; /* * Convert a date from the EPA date/time string format, which is * "mo/day/year hour:min:sec", to Vis5d format, which is two * integers giving the number of days since 1 Jan 1900 and the * number of seconds since midnight (usually GMT). */ static void convert_date( char *datestr, int *date, int *time ) { int mo, day, year, hour, min, sec, i; int days_per_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; sscanf(datestr, "%d/%d/%d %d:%d:%d", &mo, &day, &year, &hour, &min, &sec); /* printf("mo: %d day: %d year: %d hour: %d min: %d sec: %d\n", mo, day, year, hour, min, sec); */ if ((!(year % 4)) && (year % 100)) days_per_month[1] = 29; for (i=0; inr || j>nc) { printf("BAD I,J: % %d\n", i, j ); } /* note that we flip the rows from North to South - with Vis5d the first row is at the North, and rows increase toward the South - we also flip the data North to South after we get it from model_get_data - of course we could probably skip both of these flips and let the resampling take care of it */ Latitude(nr-i,j-1) = lat; Longitude(nr-i,j-1) = lon; } } fclose(f); } else if (nr == 61 && nc == 69) { float lowLat[MAXROWS][MAXCOLUMNS], lowLon[MAXROWS][MAXCOLUMNS]; f = fopen( LATLON_FILE,"r"); if (!f) { printf("Error: unable to open %s\n", LATLON_FILE ); exit(1); } while (!feof(f)) { if (fscanf( f, "%d %d %f %f\n", &j, &i, &lat, &lon )<4) { break; } else { if (i>38 || j>35) { printf("BAD I,J: % %d\n", i, j ); } lowLat[i-1][j-1] = lat; lowLon[i-1][j-1] = lon; } } for (i=0; i (17,15) */ jc = 14 + jc; /* bilinear interp of lat and lon */ lat = (1.0 - ra) * ((1.0 - ca) * lowLat[ir][jc] + ca * lowLat[ir][jc+1]) + ra * ((1.0 - ca) * lowLat[ir+1][jc] + ca * lowLat[ir+1][jc+1]); lon = (1.0 - ra) * ((1.0 - ca) * lowLon[ir][jc] + ca * lowLon[ir][jc+1]) + ra * ((1.0 - ca) * lowLon[ir+1][jc] + ca * lowLon[ir+1][jc+1]); /* note that we flip the rows from North to South - with Vis5d the first row is at the North, and rows increase toward the South - we also flip the data North to South after we get it from model_get_data - of course we could probably skip both of these flips and let the resampling take care of it */ Latitude(nr-1-i,j) = lat; Longitude(nr-1-i,j) = lon; } } fclose(f); } else { /* not "low res" or "hi res", so put it in the ocean */ for (i=0; i (lat,lon) mappings from the data file itself. */ float *gridlat, *gridlon; int iplat = -9, iplon = -9, ip, status; for (ip=0;ip0) { i--; while (varname[var][i]==' ') { varname[var][i] = 0; i--; } } */ /* printf("Varname[%d] = %s.\n", var, varname[var] );*/ varnumber[var] = var; } /* Get time/date stamps */ for (time=0;time 1) { float *grid3d = (float *) malloc( nr * nc * nl * sizeof(float) ); for (var=0;varGuard = 2; } else if (model_type==RADM) { r->Guard = 1; } else { r->Guard = 1; } #endif /* printf("numtimes=%d numvars=%d\n", numtimes, numvars );*/ /* Add grid_info nodes to grid list */ grids = 0; for (time=0;timeFileName = strdup( name ); info->Format = FILE_EPA; info->TimeStep = time; info->VarNum = varnumber[var]; info->Nr = nr; info->Nc = nc; info->Nl = nl; info->DateStamp = datestamp[time]; info->TimeStamp = timestamp[time]; info->VarName = strdup( varname[var] ); /* map projection & vcs */ info->Proj = proj; info->Vcs = vcs; append_grid( info, db ); grids++; } } /* printf("read %d grids\n", grids );*/ return grids; #else printf("Warning: Can't read EPA mm4 files on this system\n"); return 0; #endif } /* * Reverse the order of the rows in a 2-D array. */ static void flip_north_south( float data[], int rows, int columns ) { int i, nbytes; float temp[MAXCOLUMNS]; nbytes = columns * sizeof(float); for (i=0;iFileName, message)) { printf("%s\n", message); 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_epa_data\n"); close(fd); return NULL; } strcpy( species, g->VarName ); /* printf("EPA get data: t=%d v=%d\n", g->TimeStep+1, g->VarNum+1 );*/ if (!model_get_data( fd, g->TimeStep+1, g->VarNum+1, data, species, units, message)) { printf("Error in get_epa_data: %s\n", message ); free(data); close(fd); return NULL; } /* printf("begin\n"); printf("spec: %s units: %s\n", species, units ); print_min_max( data, g->Nr * g->Nc * g->Nl ); */ if (model_type==RADM) { /* multiply all values by 1000.0 */ for (i=0;iNl;i++) { flip_north_south( data + i*g->Nr*g->Nc, g->Nr, g->Nc ); } if (model_type == MM4) { /* flip top/bottom */ int size = g->Nr * g->Nc * sizeof(float); float *temp = (float *) malloc( size ); for (i=0; iNl/2 ;i++) { memcpy( temp, data + i*g->Nr*g->Nc, size ); memcpy( data + i*g->Nr*g->Nc, data + (g->Nl-1-i)*g->Nr*g->Nc, size ); memcpy( data + (g->Nl-1-i)*g->Nr*g->Nc, temp, size ); } free(temp); } /* change from row-major to column-major order */ for (i=0; iNl; i++) { transpose( data + i * g->Nr * g->Nc, data + i * g->Nr * g->Nc, g->Nr, g->Nc ); } /* print_min_max( data, g->Nr * g->Nc * g->Nl );*/ close(fd); return data; #else return NULL; #endif }