/* climateindex.c
* *
* Emilio 3/31/99
* Updated program.
* Emilio 12/3/98
* Wrote program. Debugged completely.
* COMPILE AS: gccemu climateindex
******************************************************************************/
#include "emu.h"
const char * cpszUsage = {"usage: climateindex \n\
\n\
.\n\
"};
/* local functions */
void Setup(void);
void Process(void);
void Output(void);
void writeBinaryVar(char *filename, char *Type, float *array);
void writeNCvar(int ncID, char *parameter, char *Type, char *LongType, float *array);
/* local variables */
float **TXYb_1, **TXYb0, **TXYb1, ***out;
int errnc;
#define NUMPARAM 3
#define CLINDX 0
#define CLINDXMO 1
#define SUMYR 0
#define SUM3MO 1
int main(int argc, char *argv[])
{
AssignString(&pszNCtitle, "Climate Index: 3-month minimum / annual sum");
AssignString(&pszNChist, "Climate index file created by climateindex");
Initialize(&argc, argv, DOMASK);
Setup();
Process();
Output();
CleanUp();
return(0);
}
/* ================================================================= */
void Setup(void)
{
int v, i;
/* allocate memory and initialize out[][][] TO 0.0 */
out = alloc3d_f(0,2-1,0,nVars-1,0,nRows*nCols-1);
for (v=0; v < nVars;v++)
for (i=0; i < nRows*nCols;i++)
{
out[CLINDX][v][i] = 0.0; /* climate index */
out[CLINDXMO][v][i] = 0.0; /* center month of climate index */
}
TXYb_1 = alloc2d_f(0,12-1,0,nBlockRows*nCols-1);
TXYb0 = alloc2d_f(0,12-1,0,nBlockRows*nCols-1);
TXYb1 = alloc2d_f(0,12-1,0,nBlockRows*nCols-1);
}
/* ================================================================= */
/* ======== READ DATA AND CALCULATE CLIMATE INDEX ========= */
void Process(void)
{
int v, i, iout, col, row, i0, nyblock, mo, mo_min;
float txyval_1, txyval0, txyval1, fill_val;
double stats_i[NUMPARAM];
for (v = 0; v < nVars; v++)
{
if (!bQuiet) printf("v=%d *** \n",v);
for (nyblock = 0; nyblock < nYBlocks; nyblock++)
{
ReadTXYbl(TXYb_1, pstVars[v], nyblock);
ReadTXYbl(TXYb0, pstVars[v], nyblock);
ReadTXYbl(TXYb1, pstVars[v], nyblock);
i0 = nyblock*nBlockRows*nCols;
for (i = i0; i < i0+nBlockRows*nCols; i++)
{
iout = (bOutBinary) ? i : getRowRevCol(i, &col, &row);
if (masktest(pMask[i]))
{
stats_i[SUMYR] = 0.0;
stats_i[SUM3MO] = 0.0;
stats_i[MIN] = 100000000.0;
for (mo = 0; mo < 12;mo++)
{
txyval_1 = (mo == 0) ? TXYb_1[11][i-i0]:TXYb_1[mo][i-i0];
txyval0 = TXYb0[mo][i-i0];
txyval1 = (mo == 11) ? TXYb1[0][i-i0]:TXYb1[mo][i-i0];
/* catch floating-point underflow errors w/ tolerance "TOL" */
/* if (txyval > TOL || txyval < -TOL) */
stats_i[SUMYR] += txyval0;
stats_i[SUM3MO] = txyval_1 + txyval0 + txyval1;
if (stats_i[SUM3MO] < stats_i[MIN])
{
stats_i[MIN] = stats_i[SUM3MO];
mo_min = mo+1;
}
} /* END mo FOR-LOOP (loop thru each time step) */
out[CLINDX][v][iout] = stats_i[MIN] / stats_i[SUMYR];
out[CLINDXMO][v][iout] = mo_min;
} /* END masktest() IF-BLOCK */
else
{ /* outside the pMask: FillValue */
if (pstVars[v].tEmuType == EMU_SHORT)
fill_val = (float) pstVars[v].nFillValue;
else if (pstVars[v].tEmuType == EMU_FLOAT)
fill_val = pstVars[v].fFillValue;
out[CLINDX][v][iout] = fill_val;
out[CLINDXMO][v][iout] = fill_val;
}
} /* END i-loop (read each pixel within nyblock) */
} /* END nyblock-loop (loop thru each nyblock) */
} /* END v FOR-LOOP (loop thru each variable) */
}
/* ================================================================= */
/* ============= WRITE CLIMATE INDEX TO FILE(S) ================== */
void Output(void)
{
int v, ncID, tID;
char FileName[NAMELEN]; /* Base File Name for binary files output */
if (bOutBinary) /* write output to binary files */
for (v = 0; v < nVars; v++) {
sprintf(FileName,"%s.%s", pszOutputFile, pstVars[v].param);
writeBinaryVar(FileName, ".minindx", out[CLINDX][v]);
writeBinaryVar(FileName, ".momin", out[CLINDXMO][v]);
}
else { /* write output to a single netCDF file */
/* setup new NC file from NC headers */
SetupDefaultAxes(FALSE, FALSE);
ncID = newNCsetup(&tID, pszOutputFile, pszNCtitle, pszNChist);
for (v = 0; v < nVars; v++) {
writeNCvar(ncID, pstVars[v].param, "minindx", "3-Month Min Index", out[CLINDX][v]);
writeNCvar(ncID, pstVars[v].param, "momin", "Center month of 3-Month Min", out[CLINDXMO][v]);
}
errnc = nc_close(ncID);
}
}
/* ================================================================= */
void ProcessCommandLineArgs(int * pArgc, char * argv[])
{
}
/* ================================================================= */
void LocalCleanUp(void)
{
free3d_f(out,0,2-1,0,nVars-1,0,nRows*nCols-1);
free2d_f(TXYb_1,0,12-1,0,nBlockRows*nCols-1);
free2d_f(TXYb0,0,12-1,0,nBlockRows*nCols-1);
free2d_f(TXYb1,0,12-1,0,nBlockRows*nCols-1);
}
/* ============================================================ */
void writeBinaryVar(char *filename, char *Type, float *array)
{
FILE *fout;
fout = OUTPUTfile(filename, Type);
fwrite(array, sizeof(float), nRows*nCols, fout);
fclose(fout);
}
/* ============================================================ */
void writeNCvar(int ncID, char *parameter, char *Type, char *LongType, float *array)
{
int varID; /* variable ID */
char varName[NAMELEN]; /* Name of NC variable(s) to be written */
char varLongName[NAMELEN]; /* Long Name of NC variable(s) to be written */
sprintf(varName,"%s_%s", parameter,Type);
sprintf(varLongName,"%s %s", parameter,LongType);
varID = DefNCvar(ncID, varName, EMU_FLOAT, "xy", varLongName, "0-1");
errnc = nc_put_var_float(ncID, varID, array);
}