Changeset 30266 for branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.c
- Timestamp:
- Jan 12, 2011, 9:32:08 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.c
r30021 r30266 8 8 9 9 #include "pmErrorCodes.h" 10 #include "pmVisual.h" 10 11 #include "pmSubtraction.h" 11 12 #include "pmSubtractionKernels.h" … … 16 17 #include "pmSubtractionVisual.h" 17 18 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 24 23 25 24 # define PENALTY false … … 983 982 } 984 983 985 pmSubtractionVisualPlotLeastSquares(stamps);986 984 pmSubtractionVisualShowKernels((pmSubtractionKernels *)kernels); 987 985 pmSubtractionVisualShowBasis(stamps); 986 pmSubtractionVisualPlotLeastSquares(stamps); 988 987 989 988 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate equation: %f sec", … … 1080 1079 } 1081 1080 1081 pmSubtractionVisualPlotLeastSquaresResid(stamps, sumMatrix, numStamps); 1082 1082 1083 #if 0 1083 1084 psImage *save = psImageCopy(NULL, sumMatrix, PS_TYPE_F32); … … 1087 1088 #endif 1088 1089 1090 psImage *invMatrix = NULL; 1089 1091 psVector *solution = NULL; // Solution to equation! 1090 1092 solution = psVectorAlloc(numParams, PS_TYPE_F64); … … 1096 1098 if (1) { 1097 1099 solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN); 1100 invMatrix = psMatrixInvert(NULL, sumMatrix, NULL); 1098 1101 } else { 1099 1102 psVector *PERM = NULL; … … 1104 1107 } 1105 1108 1106 # if ( 0)1109 # if (1) 1107 1110 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])); 1109 1112 } 1110 1113 # endif … … 1113 1116 kernels->solution1 = psVectorAlloc(sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 1114 1117 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); 1115 1120 } 1116 1121 … … 1120 1125 for (int i = 0; i < numKernels * numPoly; i++) { 1121 1126 kernels->solution1->data.F64[i] = solution->data.F64[i]; 1127 kernels->solution1err->data.F64[i] = sqrt(invMatrix->data.F64[i][i]); 1122 1128 } 1123 1129 … … 1131 1137 psFree(sumVector); 1132 1138 psFree(sumMatrix); 1139 psFree(invMatrix); 1133 1140 1134 1141 } else { … … 1160 1167 } 1161 1168 1169 pmSubtractionVisualPlotLeastSquaresResid(stamps, sumMatrix, numStamps); 1170 1162 1171 #if 0 1163 1172 psImage *save = psImageCopy(NULL, sumMatrix, PS_TYPE_F32); … … 1171 1180 } 1172 1181 1182 psImage *invMatrix = NULL; 1173 1183 psVector *solution = NULL; // Solution to equation! 1174 1184 solution = psVectorAlloc(numParams, PS_TYPE_F64); … … 1176 1186 1177 1187 // 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) 1181 1199 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])); 1183 1201 } 1184 1202 #endif … … 1187 1205 kernels->solution1 = psVectorAlloc(numSolution1 + 2, PS_TYPE_F64); 1188 1206 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); 1189 1209 } 1190 1210 if (!kernels->solution2) { 1191 1211 kernels->solution2 = psVectorAlloc(numSolution2, PS_TYPE_F64); 1192 1212 psVectorInit (kernels->solution2, 0.0); 1213 kernels->solution2err = psVectorAlloc(numSolution2, PS_TYPE_F64); 1214 psVectorInit(kernels->solution2err, 0.0); 1193 1215 } 1194 1216 … … 1205 1227 kernels->solution1->data.F64[i] = solution->data.F64[i] * stamps->normValue; 1206 1228 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]); 1207 1233 } 1208 1234 … … 1213 1239 kernels->solution1->data.F64[bgIndex] = 0.0; 1214 1240 1241 psFree(solution); 1242 psFree(sumVector); 1215 1243 psFree(sumMatrix); 1216 psFree(sumVector); 1217 psFree(solution); 1244 psFree(invMatrix); 1218 1245 } 1219 1246 … … 1224 1251 if (psTraceGetLevel("psModules.imcombine") >= 7) { 1225 1252 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]); 1227 1254 } 1228 1255 if (kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1229 1256 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]); 1231 1258 } 1232 1259 } … … 1280 1307 psVectorAppend(fResOuter, dOuter/sum); 1281 1308 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 1313 bool 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 1420 bool 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 1282 1584 return true; 1283 1585 }
Note:
See TracChangeset
for help on using the changeset viewer.
