/* 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);