IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 12, 2011, 9:32:08 PM (16 years ago)
Author:
eugene
Message:

add errors to kernel coeffs; calculate and plot chisq and moments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.c

    r30021 r30266  
    88
    99#include "pmErrorCodes.h"
     10#include "pmVisual.h"
    1011#include "pmSubtraction.h"
    1112#include "pmSubtractionKernels.h"
     
    1617#include "pmSubtractionVisual.h"
    1718
    18 //#define TESTING                         // TESTING output for debugging; may not work with threads!
    19 
    20 //#define USE_WEIGHT                      // Include weight (1/variance) in equation?
    21 
    22 // XXX TEST:
    23 //# define USE_WINDOW                      // window to avoid neighbor contamination
     19//# define TESTING                         // TESTING output for debugging; may not work with threads!
     20//# define USE_WEIGHT                      // Include weight (1/variance) in equation?
     21# define USE_WINDOW                      // window to avoid neighbor contamination
     22// XXX if we want to have a weight and window, we'll need to pass through to the chisq function
    2423
    2524# define PENALTY false
     
    983982    }
    984983
    985     pmSubtractionVisualPlotLeastSquares(stamps);
    986984    pmSubtractionVisualShowKernels((pmSubtractionKernels  *)kernels);
    987985    pmSubtractionVisualShowBasis(stamps);
     986    pmSubtractionVisualPlotLeastSquares(stamps);
    988987
    989988    psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate equation: %f sec",
     
    10801079        }
    10811080
     1081        pmSubtractionVisualPlotLeastSquaresResid(stamps, sumMatrix, numStamps);
     1082
    10821083#if 0
    10831084        psImage *save = psImageCopy(NULL, sumMatrix, PS_TYPE_F32);
     
    10871088#endif
    10881089
     1090        psImage *invMatrix = NULL;
    10891091        psVector *solution = NULL;                       // Solution to equation!
    10901092        solution = psVectorAlloc(numParams, PS_TYPE_F64);
     
    10961098        if (1) {
    10971099            solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN);
     1100            invMatrix = psMatrixInvert(NULL, sumMatrix, NULL);
    10981101        } else {
    10991102            psVector *PERM = NULL;
     
    11041107        }
    11051108
    1106 # if (0)
     1109# if (1)
    11071110        for (int i = 0; i < solution->n; i++) {
    1108             psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "Single solution %d: %lf\n", i, solution->data.F64[i]);
     1111            psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "Single solution %d: %lf +/- %lf\n", i, solution->data.F64[i], sqrt(invMatrix->data.F64[i][i]));
    11091112        }
    11101113# endif
     
    11131116            kernels->solution1 = psVectorAlloc(sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg
    11141117            psVectorInit(kernels->solution1, 0.0);
     1118            kernels->solution1err = psVectorAlloc(sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg
     1119            psVectorInit(kernels->solution1err, 0.0);
    11151120        }
    11161121
     
    11201125        for (int i = 0; i < numKernels * numPoly; i++) {
    11211126            kernels->solution1->data.F64[i] = solution->data.F64[i];
     1127            kernels->solution1err->data.F64[i] = sqrt(invMatrix->data.F64[i][i]);
    11221128        }
    11231129
     
    11311137        psFree(sumVector);
    11321138        psFree(sumMatrix);
     1139        psFree(invMatrix);
    11331140
    11341141    } else {
     
    11601167        }
    11611168
     1169        pmSubtractionVisualPlotLeastSquaresResid(stamps, sumMatrix, numStamps);
     1170
    11621171#if 0
    11631172        psImage *save = psImageCopy(NULL, sumMatrix, PS_TYPE_F32);
     
    11711180        }
    11721181
     1182        psImage *invMatrix = NULL;
    11731183        psVector *solution = NULL;                       // Solution to equation!
    11741184        solution = psVectorAlloc(numParams, PS_TYPE_F64);
     
    11761186
    11771187        // DUAL solution
    1178         solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN);
    1179 
    1180 #if (0)
     1188# if (1)
     1189        solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, 1e-7);
     1190        invMatrix = psMatrixInvert(NULL, sumMatrix, NULL);
     1191# endif
     1192# if (0)
     1193        psMatrixLUSolve(sumMatrix, sumVector);
     1194        solution = sumVector;
     1195        invMatrix = sumMatrix;
     1196# endif
     1197
     1198#if (1)
    11811199        for (int i = 0; i < solution->n; i++) {
    1182             fprintf(stderr, "Dual solution %d: %lf\n", i, solution->data.F64[i]);
     1200            fprintf(stderr, "Dual solution %d: %lf +/- %lf\n", i, solution->data.F64[i], sqrt(invMatrix->data.F64[i][i]));
    11831201        }
    11841202#endif
     
    11871205            kernels->solution1 = psVectorAlloc(numSolution1 + 2, PS_TYPE_F64);
    11881206            psVectorInit (kernels->solution1, 0.0);
     1207            kernels->solution1err = psVectorAlloc(numSolution1 + 2, PS_TYPE_F64); // 1 for norm, 1 for bg
     1208            psVectorInit(kernels->solution1err, 0.0);
    11891209        }
    11901210        if (!kernels->solution2) {
    11911211            kernels->solution2 = psVectorAlloc(numSolution2, PS_TYPE_F64);
    11921212            psVectorInit (kernels->solution2, 0.0);
     1213            kernels->solution2err = psVectorAlloc(numSolution2, PS_TYPE_F64);
     1214            psVectorInit(kernels->solution2err, 0.0);
    11931215        }
    11941216
     
    12051227            kernels->solution1->data.F64[i] = solution->data.F64[i] * stamps->normValue;
    12061228            kernels->solution2->data.F64[i] = solution->data.F64[i + numSolution1];
     1229
     1230            kernels->solution1err->data.F64[i] = sqrt(invMatrix->data.F64[i][i]) * stamps->normValue;
     1231            int i2 = i + numSolution1;
     1232            kernels->solution2err->data.F64[i] = sqrt(invMatrix->data.F64[i2][i2]);
    12071233        }
    12081234
     
    12131239        kernels->solution1->data.F64[bgIndex] = 0.0;
    12141240
     1241        psFree(solution);
     1242        psFree(sumVector);
    12151243        psFree(sumMatrix);
    1216         psFree(sumVector);
    1217         psFree(solution);
     1244        psFree(invMatrix);
    12181245    }
    12191246
     
    12241251    if (psTraceGetLevel("psModules.imcombine") >= 7) {
    12251252        for (int i = 0; i < kernels->solution1->n; i++) {
    1226             psTrace("psModules.imcombine", 7, "Solution 1 %d: %f\n", i, kernels->solution1->data.F64[i]);
     1253            psTrace("psModules.imcombine", 7, "Solution 1 %d: %f +/- %f\n", i, kernels->solution1->data.F64[i], kernels->solution1err->data.F64[i]);
    12271254        }
    12281255        if (kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    12291256            for (int i = 0; i < kernels->solution2->n; i++) {
    1230                 psTrace("psModules.imcombine", 7, "Solution 2 %d: %f\n", i, kernels->solution2->data.F64[i]);
     1257                psTrace("psModules.imcombine", 7, "Solution 2 %d: %f +/- %f\n", i, kernels->solution2->data.F64[i], kernels->solution2err->data.F64[i]);
    12311258            }
    12321259        }
     
    12801307    psVectorAppend(fResOuter, dOuter/sum);
    12811308    psVectorAppend(fResTotal, dTotal/sum);
     1309    return true;
     1310}
     1311
     1312// given the convolved image(s) and the residual image, calculate the second moment(s) and the chisq
     1313bool pmSubtractionChisqStats(psVector *fluxesVector, psVector *chisqVector, psVector *momentVector, psKernel *convolved1, psKernel *convolved2, psKernel *residual, psKernel *weight, psKernel *window) {
     1314
     1315    int npix = 0;
     1316    float chisq = 0;
     1317
     1318    // get the chisq
     1319    for (int y = residual->yMin; y <= residual->yMax; y++) {
     1320        for (int x = residual->xMin; x <= residual->xMax; x++) {
     1321            chisq  += PS_SQR(residual->kernel[y][x]);
     1322            npix ++;
     1323        }
     1324    }
     1325    psVectorAppend(chisqVector, chisq / npix);
     1326
     1327    float value1 = 0;
     1328    float value2 = 0;
     1329    float flux2 = 0;
     1330    float fluxX = 0;
     1331    float fluxY = 0;
     1332    float fluxX2 = 0;
     1333    float fluxY2 = 0;
     1334
     1335    float fluxC1 = 0;
     1336    float fluxC2 = 0;
     1337
     1338    float moment = 0;
     1339
     1340    // get the moments from convolved1
     1341    if (convolved1) {
     1342        for (int y = residual->yMin; y <= residual->yMax; y++) {
     1343            for (int x = residual->xMin; x <= residual->xMax; x++) {
     1344                value1  = convolved1->kernel[y][x];
     1345                value2  = PS_SQR(value1);
     1346
     1347                if (weight) {
     1348                    value2 *= weight->kernel[y][x];
     1349                }
     1350                if (window) {
     1351                    value1 *= window->kernel[y][x];
     1352                    value2 *= window->kernel[y][x];
     1353                }
     1354
     1355                fluxC1 += value1;
     1356                flux2  += value2;
     1357                fluxX  += x * value2;
     1358                fluxY  += y * value2;
     1359                fluxX2 += PS_SQR(x) * value2;
     1360                fluxY2 += PS_SQR(y) * value2;
     1361            }
     1362        }
     1363        // float Mx = fluxX / flux2;
     1364        // float My = fluxY / flux2;
     1365        float Mxx = fluxX2 / flux2;
     1366        float Myy = fluxY2 / flux2;
     1367
     1368        // fprintf (stderr, "conv1, flux2: %f, Mx: %f, My: %f, Mxx: %f, Myy: %f, chisq: %f, npix: %d\n", flux2, Mx, My, Mxx, Myy, chisq, npix);
     1369        moment += Mxx + Myy;
     1370    }
     1371
     1372    // get the moments from convolved1
     1373    if (convolved2) {
     1374        for (int y = residual->yMin; y <= residual->yMax; y++) {
     1375            for (int x = residual->xMin; x <= residual->xMax; x++) {
     1376                value1  = convolved2->kernel[y][x];
     1377                value2  = PS_SQR(value1);
     1378
     1379                if (weight) {
     1380                    value2 *= weight->kernel[y][x];
     1381                }
     1382                if (window) {
     1383                    value1 *= window->kernel[y][x];
     1384                    value2 *= window->kernel[y][x];
     1385                }
     1386
     1387                fluxC2 += value1;
     1388                flux2  += value2;
     1389                fluxX  += x * value2;
     1390                fluxY  += y * value2;
     1391                fluxX2 += PS_SQR(x) * value2;
     1392                fluxY2 += PS_SQR(y) * value2;
     1393            }
     1394        }
     1395        // float Mx = fluxX / flux2;
     1396        // float My = fluxY / flux2;
     1397        float Mxx = fluxX2 / flux2;
     1398        float Myy = fluxY2 / flux2;
     1399
     1400        // fprintf (stderr, "conv2, flux2: %f, Mx: %f, My: %f, Mxx: %f, Myy: %f, chisq: %f, npix: %d\n", flux2, Mx, My, Mxx, Myy, chisq, npix);
     1401        moment += Mxx + Myy;
     1402    }
     1403
     1404    float flux = fluxC1 + fluxC2;
     1405   
     1406    if (convolved1 && convolved2) {
     1407        moment *= 0.5;
     1408        flux *= 0.5;
     1409    }
     1410    psVectorAppend(momentVector, moment);
     1411    psVectorAppend(fluxesVector, flux);
     1412    return true;
     1413}
     1414
     1415// typedef struct {
     1416//     float moment;
     1417//     float chisq;
     1418// } diffStat;
     1419
     1420bool pmSubtractionCalculateChisqAndMoments(pmSubtractionStampList *stamps,
     1421                                           pmSubtractionKernels *kernels)
     1422{
     1423    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, NULL);
     1424    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, NULL);
     1425    PM_ASSERT_SUBTRACTION_KERNELS_SOLUTION(kernels, NULL);
     1426
     1427    psVector *fluxes = psVectorAllocEmpty(stamps->num, PS_TYPE_F32);
     1428    psVector *chisq = psVectorAllocEmpty(stamps->num, PS_TYPE_F32);
     1429    psVector *moments = psVectorAllocEmpty(stamps->num, PS_TYPE_F32);
     1430
     1431    int footprint = stamps->footprint; // Half-size of stamps
     1432    int numKernels = kernels->num;      // Number of kernels
     1433
     1434    psImage *polyValues = NULL;         // Polynomial values
     1435
     1436    psKernel *residual = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image
     1437
     1438    // storage for the convolved source image (only convolved1 is used in SINGLE mode)
     1439    psKernel *convolved1 = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image
     1440    psKernel *convolved2 = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image
     1441
     1442    for (int i = 0; i < stamps->num; i++) {
     1443        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // The stamp of interest
     1444        if (stamp->status != PM_SUBTRACTION_STAMP_USED) {
     1445            continue;
     1446        }
     1447
     1448        // Calculate coefficients of the kernel basis functions
     1449        polyValues = p_pmSubtractionPolynomial(polyValues, kernels->spatialOrder, stamp->xNorm, stamp->yNorm);
     1450        double norm = p_pmSubtractionSolutionNorm(kernels); // Normalisation
     1451        double background = p_pmSubtractionSolutionBackground(kernels, polyValues);// Difference in background
     1452
     1453        // Calculate residuals
     1454        psImageInit(residual->image, 0.0);
     1455
     1456    psKernel *weight = NULL;
     1457    psKernel *window = NULL;
     1458
     1459#ifdef USE_WEIGHT
     1460    weight = stamp->weight;
     1461#endif
     1462#ifdef USE_WINDOW
     1463    window = stamps->window;
     1464#endif
     1465
     1466        if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) {
     1467
     1468            // the single-direction psf match code attempts to find the kernel such that:
     1469            // source * kernel = target.  we need to assign 'source' and 'target' correctly
     1470            // depending on which of image1 or image2 we asked to be convolved.
     1471
     1472            psKernel *target;           // Target postage stamp (convolve source to match the target)
     1473            psKernel *source;           // Source postage stamp (convolve source to match the target)
     1474            psArray *convolutions;      // Convolution postage stamps for each kernel basis function
     1475
     1476            // init the accumulation image
     1477            psImageInit(convolved1->image, 0.0);
     1478
     1479            switch (kernels->mode) {
     1480              case PM_SUBTRACTION_MODE_1:
     1481                target = stamp->image2;
     1482                source = stamp->image1;
     1483                convolutions = stamp->convolutions1;
     1484                break;
     1485              case PM_SUBTRACTION_MODE_2:
     1486                target = stamp->image1;
     1487                source = stamp->image2;
     1488                convolutions = stamp->convolutions2;
     1489                break;
     1490              default:
     1491                psAbort("Unsupported subtraction mode: %x", kernels->mode);
     1492            }
     1493
     1494            // generate the convolved source image (sum over kernels)
     1495            for (int j = 0; j < numKernels; j++) {
     1496                psKernel *convolution = convolutions->data[j]; // Convolution
     1497                double coefficient = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, false); // Coefficient
     1498                for (int y = - footprint; y <= footprint; y++) {
     1499                    for (int x = - footprint; x <= footprint; x++) {
     1500                        convolved1->kernel[y][x] += convolution->kernel[y][x] * coefficient;
     1501                    }
     1502                }
     1503            }
     1504
     1505            // generate the residual image
     1506            for (int y = - footprint; y <= footprint; y++) {
     1507                for (int x = - footprint; x <= footprint; x++) {
     1508                    convolved1->kernel[y][x] += source->kernel[y][x] * norm;
     1509                    residual->kernel[y][x] = target->kernel[y][x] - convolved1->kernel[y][x] - background;
     1510                }
     1511            }
     1512            // XXX if we want to have a weight and window, we'll need to pass through to here
     1513            pmSubtractionChisqStats(fluxes, chisq, moments, convolved1, NULL, residual, weight, window);
     1514
     1515        } else {
     1516
     1517            // Dual convolution
     1518            psArray *convolutions1 = stamp->convolutions1; // Convolutions of the first image
     1519            psArray *convolutions2 = stamp->convolutions2; // Convolutions of the second image
     1520            psKernel *image1 = stamp->image1; // The first image
     1521            psKernel *image2 = stamp->image2; // The second image
     1522
     1523            // init the accumulation images
     1524            psImageInit(convolved1->image, 0.0);
     1525            psImageInit(convolved2->image, 0.0);
     1526
     1527            for (int j = 0; j < numKernels; j++) {
     1528                psKernel *conv1 = convolutions1->data[j]; // Convolution of first image
     1529                psKernel *conv2 = convolutions2->data[j]; // Convolution of second image
     1530                double coeff1 = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, false); // Coefficient 1
     1531                double coeff2 = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, true); // Coefficient 2
     1532
     1533                for (int y = - footprint; y <= footprint; y++) {
     1534                    for (int x = - footprint; x <= footprint; x++) {
     1535                        // NOTE sign for coeff2
     1536                        convolved1->kernel[y][x] += +conv1->kernel[y][x] * coeff1;
     1537                        convolved2->kernel[y][x] += -conv2->kernel[y][x] * coeff2;
     1538                    }
     1539                }
     1540            }
     1541
     1542            for (int y = - footprint; y <= footprint; y++) {
     1543                for (int x = - footprint; x <= footprint; x++) {
     1544                    convolved1->kernel[y][x] += image1->kernel[y][x] * norm;
     1545                    convolved2->kernel[y][x] += image2->kernel[y][x];
     1546                    residual->kernel[y][x] = convolved2->kernel[y][x] - convolved1->kernel[y][x] - background;
     1547                }
     1548            }
     1549
     1550            if (0) {
     1551                psFitsWriteImageSimple("conv1.fits", convolved1->image, NULL);
     1552                psFitsWriteImageSimple("conv2.fits", convolved2->image, NULL);
     1553                psFitsWriteImageSimple("resid.fits", residual->image,   NULL);
     1554                pmVisualAskUser(NULL);
     1555            }
     1556
     1557            pmSubtractionChisqStats(fluxes, chisq, moments, convolved1, convolved2, residual, weight, window);
     1558        }
     1559    }
     1560
     1561    pmSubtractionVisualPlotChisqAndMoments(fluxes, chisq, moments);
     1562
     1563    // find the mean chisq and mean moment
     1564    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
     1565    psVectorStats (stats, chisq, NULL, NULL, 0);
     1566    float chisqValue = stats->sampleMean;
     1567
     1568    psStatsInit(stats);
     1569    psVectorStats (stats, moments, NULL, NULL, 0);
     1570    float momentValue = stats->sampleMean;
     1571
     1572    fprintf (stderr, "chisq: %f, moment: %f\n", chisqValue, momentValue);
     1573
     1574    psFree(stats);
     1575    psFree(chisq);
     1576    psFree(fluxes);
     1577    psFree(moments);
     1578
     1579    psFree(residual);
     1580    psFree(convolved1);
     1581    psFree(convolved2);
     1582    psFree(polyValues);
     1583
    12821584    return true;
    12831585}
Note: See TracChangeset for help on using the changeset viewer.