/** @file tst_pmFlatField.c
 *
 *  @brief Contains the tests for pmNonLinear.c:
 *
 * test00: This code will create a simple polynomial, and call
 * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
 * N), (N, 1), (N, N)].  
 *
 * test01: This code will create simple table lookup vectors, and call
 * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
 * N), (N, 1), (N, N)].  
 *
 *  @author GLG, MHPCC
 *
 *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2004-10-14 23:52:09 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */

#include "psTest.h"
#include "pslib.h"
#include "pmNonLinear.h"
static int test00(void);
static int test01(void);
testDescription tests[] = {
                              {test00, 000, "pmNonLinearityPolynomial", 0, false},
                              {test01, 000, "pmNonLinearityLookup", 0, false},
                              {NULL}
                          };


int main(int argc, char* argv[])
{
    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
}

#define NUM_ROWS 8
#define NUM_COLS 8
int doNonLinearityPolynomialTest(int numCols, int numRows)
{
    int i;
    int j;
    float actual;
    float expect;
    int testStatus = 0;
    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    psReadout *myReadout = psReadoutAlloc(numCols, numRows, myImage);
    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
    myPoly->coeff[1] = 1.0;

    for (i=0;i<numRows;i++) {
        for (j=0;j<numCols;j++) {
            myReadout->image->data.F32[i][j] = (float) (i + j);
        }
    }

    myReadout = pmNonLinearityPolynomial(myReadout, myPoly);
    for (i=0;i<numRows;i++) {
        for (j=0;j<numCols;j++) {
            expect = psPolynomial1DEval((float) (i + j), myPoly);
            actual = myReadout->image->data.F32[i][j];
            if (FLT_EPSILON < fabs(expect - actual)) {
                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
                testStatus = 1;
            }
        }
    }


    psFree(myReadout);
    psFree(myPoly);
    return(testStatus);
}

int test00( void )
{
    int testStatus = 0;

    testStatus |= doNonLinearityPolynomialTest(1, 1);
    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, 1);
    testStatus |= doNonLinearityPolynomialTest(1, NUM_ROWS);
    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, NUM_ROWS);

    return(testStatus);
}

int doNonLinearityLookupTest(int numCols, int numRows)
{
    int i;
    int j;
    float actual;
    float expect;
    int testStatus = 0;
    int tableSize = PS_MAX(numCols, numRows)*2;
    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    psReadout *myReadout = psReadoutAlloc(numCols, numRows, myImage);
    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);

    for (i=0;i<numRows;i++) {
        for (j=0;j<numCols;j++) {
            myReadout->image->data.F32[i][j] = (float) (i + j);
        }
    }

    for (i=0;i<tableSize;i++) {
        in->data.F32[i] = (float) i;
        out->data.F32[i] = (float) (2 * i);
    }

    myReadout = pmNonLinearityLookup(myReadout, in, out);
    for (i=0;i<numRows;i++) {
        for (j=0;j<numCols;j++) {
            expect = (float) (2 * (i + j));
            actual = myReadout->image->data.F32[i][j];
            if (FLT_EPSILON < fabs(expect - actual)) {
                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
                testStatus = 1;
            }
        }
    }


    psFree(myReadout);
    psFree(in);
    psFree(out);
    return(testStatus);
}

int test01( void )
{
    int testStatus = 0;

    testStatus |= doNonLinearityLookupTest(1, 1);
    testStatus |= doNonLinearityLookupTest(NUM_COLS, 1);
    testStatus |= doNonLinearityLookupTest(1, NUM_ROWS);
    testStatus |= doNonLinearityLookupTest (NUM_COLS, NUM_ROWS);

    return(testStatus);
}
