/* emu.h
* *
* Emilio 4/16/2001
* Added constant LONGLINELEN, for handling long char lines.
* *
* Header file for all the C programs written to analyze binary and NetCDF
* input and output for modelling using the Environmental Modeling Utilities,
* or "EMU" package.
******************************************************************************/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "unitconv.h"
#ifdef PC
#include <float.h>
#endif
#ifdef UNIX
#include <ieeefp.h>
#endif
#ifdef NONETCDF
#include "nonetcdf.h"
#else
#include <netcdf.h>
#endif
#define TRUE 1
#define FALSE 0
#define NONE -1
#define TOL 0.0001
#define FILENAMELEN 120
#define NAMELEN 60
#define LINELEN 300
#define LONGLINELEN 5000
#define FMIN 1.0e-37F /* actually these go to 38, but for cross system */
#define FMAX 1.0e+37F /* compatibility we'll limit it to this. */
#define SMIN -32768
#define SMAX 32767
#define FSMAX 32767.0F
typedef int BOOL; /* Hungarian b */
typedef unsigned char BYTE; /* Hungarian by */
typedef short int SHORT; /* Hungarian s, n is for straight int,
* sz is for char * string */
typedef unsigned short int WORD; /* Hungarian w */
typedef long int LONG; /* Hungarian l */
typedef unsigned long DWORD; /* Hungarian dw */
BOOL bProcess;
BOOL bVerbose;
BOOL bQuiet;
BOOL bInteractive;
BOOL bDebug;
BOOL bNoMask;
BOOL bOutBinary;
char *pszOutputFile, *pszNCGenFile, *pszNCtitle, *pszNChist;
int errnc;
char *pszOutputFilePath;
/* ====== Generic constant names used in several applications ====== */
#define CELLCNT 0
#define COUNT 1
#define AREA 1
#define SUM 0
#define SUM2 1
#define SUM2XY 2
#define MEAN 0
#define SD 1
#define MIN 2
#define MAX 3
/* ============= OPTION ARGUMENTS FOR Initialize() FUNCTION =============== */
#define NOMASK 0
#define DOMASK 1
/* ============== CUSTOMAZIBLE, GLOBAL PARAMETER ARRAYS =================== */
int nParams; /* total number of parameters */
float *P; /* parameter array */
int nStrParams; /* total number of string parameters */
char *szP[10]; /* array of string parameters (10 max) */
/* ======= GLOBAL VARIABLES USED TO HOLD GEOGRAPHIC-SPATIAL INFORMATION === */
int nYBlocks, nBlockRows;
int nRows, nCols; /* size of image */
float fLatTop, fLatBtm, fLonRight, fLonLeft; /* Geographic, lat-lon frame */
float fVScale, fHScale; /* size of each pixel, in degrees */
int nOutRows, nOutCols; /* size of image */
/* ===== GLOBAL VARIABLES USED TO HOLD TIME AND TIME AXIS INFORMATION ====== */
#define NOTIME -1
#define MONTHLY 0
#define MONMEAN 1
#define ANNUAL 2
/* FirstMonth & LastMonth are NOT base 0 (ie, january = 1, not 0) */
int YEARORIGIN;
int nFirstYear; /* FIRST YEAR */
int nFirstMonth; /* FIRST MONTH */
int nLastYear; /* LAST YEAR */
int nLastMonth; /* LAST MONTH */
int nTotalYears; /* TOTAL NUMBER OF YEARS */
int nTimeSteps; /* TOTAL NUMBER OF MONTHS (TIME STEPS) */
int nTotalMonths[YEAR2MONTH]; /* TOTAL NUMBER FOR EACH MONTH */
/* ======= GLOBAL VARIABLES USED FOR HANDLING OF FILE PATHS & NAMES ======== */
#define PATH 0
#define PARAM 1
/* ======= DEFINITION OF INFORMATION FOR A VARIABLE ======================= */
typedef enum
{
INTEL = 1,
DEC = 1,
MOTOROLA = 2,
} byteorder_type;
byteorder_type tByteOrder;
typedef enum
{
EMU_BYTE = 1, /* unsigned 1 byte integer */
EMU_CHAR = 2, /* ISO/ASCII character */
EMU_SHORT = 3, /* signed 2 byte integer */
EMU_INT = 4, /* signed 4 byte integer */
EMU_FLOAT = 5, /* single precision floating point number */
EMU_DOUBLE = 6, /* double precision floating point number */
EMU_USHORT = 7, /* Unsigned 2 byte integer */
EMU_WORD = 7, /* Unsigned 2 byte integer */
EMU_LONG = 4, /* Signed 4 byte integer */
EMU_ULONG = 8, /* Unsigned 4 byte integer */
EMU_DWORD = 8, /* Unsigned 4 byte integer */
} emu_type;
typedef enum
{
BADTYPE = 0,
FSQ = 1,
BSQ = 2,
BIL = 3,
BIP = 4,
} dataorg_type;
typedef struct _dynfilelist
{
char szName[FILENAMELEN]; /* Name of associated dyn file element */
char szFormat[FILENAMELEN]; /* Name of associated dyn file element */
int nElements; /* number of elemetns */
char * * ppszElement;
} DYNFILE;
typedef struct _var
{
/* ===== General Characteristics ===== */
char name[20]; /* Variable name */
char filetype[15]; /* File type: bin|intel|motorola, ascii, nc */
char path[FILENAMELEN]; /* File Path */
char param[FILENAMELEN]; /* File Name */
int nDyn; /* number of dynamic file elements */
DYNFILE *pstDyn; /* array of dynamic file elements */
BOOL bIsMetaData; /* Variable is a place holder for metadata */
/* ===== Optional, Variable-specific parameters ===== */
int nParams; /* total number of numeric float-type parameters */
float *P; /* array of numeric float-type parameters */
int nStrParams; /* total number of string parameters */
char *szP[10]; /* array of string parameters (10 max) */
/* ===== Spatial (X-Y) Characteristics ===== */
int nCols; /* Number of columns */
int nRows; /* Number of rows */
char YDir[10]; /* Orientation of Y axis: "normal" or "rev" */
/* ===== Time Axis Characteristics ======= */
short tTimeType; /* Mean-Axis type: MONTHLY, MONMEAN, ANNUAL */
double t1; /* value in months of 1st time step in time coord */
char szUnit[NAMELEN]; /* Time axis units (month, hour, day) */
short YearOrigin; /* Origin Year for this variable (mostly nc vars) */
/* ===== Data Type, Compression, Nodata Value And Type ===== */
emu_type tEmuType; /* EMU Data Type */
float scale_factor; /* scale factor (gain), if present */
float add_offset; /* offset factor (offset), if present */
short nFillValue;
float fFillValue;
/* ===== Image Data Elements ===== */
dataorg_type tDataOrg; /* Data Organization Type (bil, fsq, bsq, etc) */
int nBands; /* number of bands, for multi-band images */
/* ===== Binary-Specific Elements ===== */
BOOL bByteSwap; /* Byte Swap (with respect to the default) */
/* ===== ASCII-Specific Elements ===== */
char delimeter; /* Delimeter character used as field-separator */
/* ===== Netcdf-Specific Elements ===== */
int ncid; /* netCDF file id, if file is netCDF */
int var_id; /* id of variable if file is netCDF */
} VAR;
VAR * pstVars;
VAR * pstOutput;
VAR * pstInput;
int nVars;
/* == GLOBAL VARIABLES RELATED TO MASKS, MASK IDS, AND CELLCOUNTS PER MASK ID */
#define SITESMAX 500 /* max number of unique IDs from mask file */
char szMaskType[15]; /* rangeposval OR singleposval OR rangefileIDs *
* OR rangefileID1 */
/* (ALL MASK VALUES MUST BE POSITIVE) */
LONG * pMask; /* pointer that will be allocated space *
* to contain mask array */
int nRegionID; /* selected single mask ID */
int FlMskSitesN; /* Total number of unique IDs > 0 in the mask file */
int *FlMskSitesIDs; /* Array containing all unique IDs in the mask file */
int *FlMskSitesCellcount; /* Array of cellcount per unique ID in mask file */
int FlMskTotCellcount; /* Total cellcount for all unique IDs in mask file */
double *FlMskSitesArea; /* Array of area (m2) per unique ID in mask file */
double FlMskTotArea; /* Total area (m2) for all unique IDs in mask file */
int MskSitesN; /* Total number of IDs that will be printed out */
int *MskSitesIDs;
int MskTotCellcount; /* Total cellcount for selected IDs */
double MskTotArea; /* Total area (m2) for selected IDs */
/* With rangefileIDs, MskTotCellcount is used mainly when a single *
* aggregate ID is requested; with rangeposval it will be set to be *
* equal to FlMskTotCellcount */
typedef struct _masks
{
int ID; /* Aggregate ID */
int cellcount; /* Total number of cells within the *
* Aggregate ID zone */
double area; /* Total area (in m^2) encompassed by *
* Aggregate ID zone */
int nMaskids; /* Number of IDs in Aggregate ID */
int *maskids; /* Array containing all the IDs in the *
* Aggregate ID */
} MASK;
MASK *Masks;
/* ==== GLOBAL STRUCTURE USED TO CREATE & HANDLE A "Z" NETCDF DIMENSION ===== */
typedef enum
{
XYZT = 1111,
XYZ = 1110,
XYT = 1101,
XY = 1100,
XZT = 1011,
ZT = 11,
Z = 10,
T = 1,
} AXES_TYPE;
AXES_TYPE AxesType;
typedef struct _axis
{
BOOL active; /* 1 = yes, 0 = no (TRUE/FALSE) */
char name[20];
char lname[30];
char units[30];
short point_spacing_even; /* 1 = yes, 0 = no */
float valid_range[2]; /* 1st value is min, 2nd value is max */
int length; /* number of values */
double *values; /* array containing the actual values */
/* fields specific to z/depth/elev axes */
char positiveOrient[5]; /* "up" or "down" */
/* fields specific to time axes */
char time_origin[30];
BOOL monmean;
char time_modulo[2];
} AXIS;
AXIS stAxes[4];
/* === STRUCTS FOR HANDLING BITMAP (.bmp) IMAGE FILES === */
typedef struct _BITMAPFILEHEADER
{
short bfType;
long bfSize;
short bfRes1;
short bfRes2;
long bfOffBits;
} BITMAPFILEHEADER;
typedef struct _BITMAPINFOHEADER
{
long biSize;
long biWidth;
long biHeight;
short int biPlanes;
short biBitCount;
long biCompression;
long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
long biClrUsed;
long biClrImportant;
} BITMAPINFOHEADER;
/* ===== GENERAL MACROS ===== */
static float sqrarg;
static double dsqrarg;
unsigned short tempr;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr;
#define GMAX(a,b) (((a) > (b)) ? (a) : (b));
#define GMIN(a,b) (((a) < (b)) ? (a) : (b));
/* ================ FUNCTIONS defined within each application =============== */
void ProcessCommandLineArgs(int * pArgc, char * argv[]);
void LocalCleanUp(void);
/* =================== FUNCTIONS FOUND IN function.c =================== */
void Initialize(int * argc, char * argv[], short option);
short GetVarNo(char *varname);
void CopyVar(VAR *varto, VAR *varfrom);
nc_type EMUtoNCType(emu_type EmuType);
emu_type NCtoEMUType(nc_type NCType);
size_t EmuTypeSize(emu_type EmuType);
void CleanUp(void);
void GlobalCleanUp(void);
/* === FUNCTIONS FOUND IN function.c, kept for backward compatibility === */
void SimpleInitialize(int * argc, char * argv[]);
void ReadVariable(VAR * pstVar, char * pszVarKeyword);
void ReadInput(void);
void ReadOutput(void);
/* =================== FUNCTIONS FOUND IN io.c ====================== */
void ReadXY(float *pfData, VAR var, int year, int month);
void ReadT(float *ts4byte, VAR var, long int i);
void ReadTXYbl(float **TsXYblock4byte, VAR var, int nyblock);
void ReadXBData(float * * ppfData, VAR * pVar, int y);
void ReadYXBData(float * * * pppfData, VAR * pVar, int yStart, int yExtent, int xStart, int xExtent);
void WriteXY(float * pfData, VAR var, int nYear, int nMonth);
void WriteXBData(float * * ppfData, VAR * pVar, int y);
void WriteYXBData(float * * * pppfData, VAR * pVar, int yStart, int yExtent, int xStart, int xExtent);
void WriteBMP(VAR * pVar, BYTE * * ppbyData);
void WriteBinaryOutput(FILE * fp, float * pfData, emu_type tEmuType, int nElements);
FILE *OUTPUTfile(char *filename, char *extension);
/* === FUNCTIONS FOUND IN io.c, kept for backward compatibility === */
void ReadXYData(float * pfData, VAR * pVar);
void WriteXYMap(float * pfData, VAR * pVar, int nYear, int nMonth);
void WriteXYData(float * pfData, VAR * pVar);
/* =================== FUNCTIONS FOUND IN masks.c ====================== */
BOOL masktest(int maskid);
int siteindex(int *siteids, int maskid);
/* =================== FUNCTIONS FOUND IN ncoutput.c =================== */
void SetupDefaultAxes(BOOL UseTimeAxis, BOOL monmean);
void FillAxisProp(char *name, char *lname, char *units, short point_spacing_even,
float min, float max, int length, double *values, BOOL positiveDown);
void FillTAxisProp(char *name, char *lname, char *units, short point_spacing_even,
float min, float max, int length, double *values, char *time_origin, BOOL Tmonmean);
int newNCsetup(int *tID, char *pszOutputFile, char *title, char *history);
void CreateCDFFromCDL(char * pszCDL, char * pszCDF, char * pszTitle,
char * pszHistory, char * timeunits, char * timeorigin, char * pszType);
int DefNCvar(int ncID, char *name, emu_type EmuType, char *dims, char *longname, char *units);
void DefNCvarsFromNCs(int ncIDin, char * pszNC, emu_type EmuType);
void AddNCCompressionAttributes(int ncID, int varID, float scale_factor, float add_offset);
void AddAttribute(int ncIDin, char *pszNC, int nVarIDin, char *pszVar,
char *pszAtt, emu_type EmuType, int nLen, void *pvValues);
/* =================== FUNCTIONS FOUND IN TimeUtilities.c =================== */
/* define the date on which the Gregorian calendar began: October 15, 1582 */
#define GREGORIAN_START (15 + 31L * (10 + 12L * 1582))
#define GREGORIAN_CROSSOVER 2299161
/* time function prototypes */
/* a postive year signifies AD; negative, BC. Remember that the year after 1 BC was */
/* 1 AD. The Solar day refers to the day of the year (Gregorian year), with */
/* January 1st of each year being Solar day 0. */
void GregorianToJulianDay(int nMonth, int nDay, int nYear, long *plJulianDay);
void GregorianToSolarDay(int nMonth, int nDay, int nYear, int *pnSolarDay);
void JulianToGregorianDay(long lJulianDay, int *pnMonth, int *pnDay, int *pnYear);
void JulianToSolarDay(long lJulianDay, int *pnSolarDay);
void SolarToGregorianDay(int nSolarDay, int nYear, int *pnMonth, int *pnDay);
void SolarToJulianDay(int nSolarDay, int nYear, long *plJulianDay);
BOOL IsLeapYear(int nYear);
short GetDaysInMonth(short month, int nYear);
int GetDayOfWeekIndex(long lJulianDay);
void GetDayOfWeekName(long lJulianDay, char *pszDayOfWeek);
/* =================== FUNCTIONS FOUND IN util.c =================== */
void getyrmonth(int tvar, int *year, int *month);
void NEXTyrmo(int *yr, int *mo);
long int getRowRevCol(long int i, int *col, int *row);
double cellarea(int i);
double area(double latitude, double vscale, double hscale);
int roundoff(double value);
float CorrCoef(float * pf1, float * pf2, int nOffset);
float Mean(float * * ppfData, int nOffset);
void SwapBytes(BYTE * pbyData, int nSwapBytes, int nBytes);
int IsBad(double dTest);
/* string handling functions */
int istype(char *var, char *type);
void AssignString(char * * ppszTarget, char * pszSource);
char *GetQuotedText(int * i, char * argv[]);
void DropTrailingSpaces(char *pszStr);
void DropSurroundingQuotes(char *pszStr);
void ClearString(char *string, int StringLen);
int strcnt(char * psz, char c);
int GetLineElements(char **ppszArgs, char *pszLine, char delimeter);
void GetFixedWidthElements(char *ppszArgs[], int TotElements, char *pszLine, int indices[][2]);
void FreeLineElements(char **StringArray, int TotElements);
/* file handling functions (esp. text files) */
void DoesFileExist(char * pszFile);
int fgetline(char *line, int lim, FILE *fin);
long GetTotalLines(FILE *fdat);
BOOL SkipLines(FILE *fid, long SkipSize);
void PrintTime(void);
void Warning(char * pszWarningString, char * pszArg);
void ExitError(char * pszErrorString, char * arg);
void nrerror(char error_text[], char *errorvar);
/* ----------- allocation/deallocation of 1-D arrays ------------ */
VAR *alloc1d_VAR(long nl, long nh);
void VAR">free1d_VAR(VAR *v, long nl, long nh);
MASK *alloc1d_MASK(long nl, long nh);
void MASK">free1d_MASK(MASK *v, long nl, long nh);
double *alloc1d_d(long nl, long nh);
void free1d_d(double *v, long nl, long nh);
float *alloc1d_f(long nl, long nh);
void free1d_f(float *v, long nl, long nh);
int *alloc1d_i(long nl, long nh);
void free1d_i(int *v, long nl, long nh);
long *alloc1d_l(long nl, long nh);
void free1d_l(long *v, long nl, long nh);
short *alloc1d_s(long nl, long nh);
void free1d_s(short *v, long nl, long nh);
unsigned short *alloc1d_us(long nl, long nh);
void free1d_us(unsigned short *v, long nl, long nh);
unsigned char *alloc1d_uc(long nl, long nh);
void free1d_uc(unsigned char *v, long nl, long nh);
/* ----------- allocation/deallocation of 2-D arrays ------------ */
double **alloc2d_d(long nrl, long nrh, long ncl, long nch);
void free2d_d(double **m, long nrl, long nrh, long ncl, long nch);
float **alloc2d_f(long nrl, long nrh, long ncl, long nch);
void free2d_f(float **m, long nrl, long nrh, long ncl, long nch);
LONG **alloc2d_l(long nrl, long nrh, long ncl, long nch);
void free2d_l(LONG **m, long nrl, long nrh, long ncl, long nch);
short **alloc2d_s(long nrl, long nrh, long ncl, long nch);
void free2d_s(short **m, long nrl, long nrh, long ncl, long nch);
BYTE **alloc2d_by(long nrl, long nrh, long ncl, long nch);
void free2d_by(BYTE **m, long nrl, long nrh, long ncl, long nch);
/* ----------- allocation/deallocation of 3-D arrays ------------ */
short ***alloc3d_s(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free3d_s(short ***t, long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
float ***alloc3d_f(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free3d_f(float ***t, long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
double ***alloc3d_d(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free3d_d(double ***t, long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void CheckDeallocation (void);
void FreeVectorToMatrix (float * * ppfMatrix);
float * * VectorToMatrix (float * pfVector);