Changeset 30289
- Timestamp:
- Jan 17, 2011, 5:18:09 PM (15 years ago)
- Location:
- branches/eam_branches/ipp-20101205/psModules/src/imcombine
- Files:
-
- 5 edited
-
pmSubtractionEquation.c (modified) (47 diffs)
-
pmSubtractionEquation.h (modified) (3 diffs)
-
pmSubtractionStamps.c (modified) (7 diffs)
-
pmSubtractionVisual.c (modified) (11 diffs)
-
pmSubtractionVisual.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.c
r30266 r30289 20 20 //# define USE_WEIGHT // Include weight (1/variance) in equation? 21 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 22 23 /* I believe we want to apply the WEIGHT to the chisq portions of the calculation (but not the WINDOW), 24 * and the WINDOW to the moments portiosn of the calculations (but not the WEIGHT) 25 * 26 */ 23 27 24 28 # define PENALTY false … … 106 110 cc *= weight->kernel[y][x]; 107 111 } 108 if (window) { 112 // XXX NOTE: do NOT apply the window to the chisq portions of the calculation 113 if (false && window) { 109 114 cc *= window->kernel[y][x]; 110 115 } … … 137 142 rc *= wtVal; 138 143 } 139 if (window) { 144 // XXX NOTE: do NOT apply the window to the chisq portions of the calculation 145 if (false && window) { 140 146 float winVal = window->kernel[y][x]; 141 147 ic *= winVal; … … 172 178 } 173 179 180 # define RENORM_BY_FLUX 0 174 181 175 182 // Calculate the least-squares matrix and vector for dual convolution … … 267 274 for (int y = - footprint; y <= footprint; y++) { 268 275 for (int x = - footprint; x <= footprint; x++) { 276 277 // XXX NOTE: clipping low S/N pixels does not seem to work very well 278 if (false && weight) { 279 float i1 = image1->kernel[y][x]; 280 float i2 = image2->kernel[y][x]; 281 float sn = (i1 + i2) / sqrt (weight->kernel[y][x]); 282 if (sn < 0.5) continue; 283 } 284 269 285 double aa = iConv1->kernel[y][x] * jConv1->kernel[y][x] * PS_SQR(normValue); 270 286 double bb = iConv2->kernel[y][x] * jConv2->kernel[y][x]; 271 287 double ab = iConv1->kernel[y][x] * jConv2->kernel[y][x] * normValue; 272 if (weight) { 273 float wtVal = weight->kernel[y][x]; 274 aa *= wtVal; 275 bb *= wtVal; 276 ab *= wtVal; 277 } 278 if (window) { 279 float wtVal = window->kernel[y][x]; 280 aa *= wtVal; 281 bb *= wtVal; 282 ab *= wtVal; 283 } 284 sumAA += aa; 285 sumBB += bb; 286 sumAB += ab; 288 289 float wtVal = (weight) ? weight->kernel[y][x] : 1.0; 290 sumAA += wtVal*aa; 291 sumBB += wtVal*bb; 292 sumAB += wtVal*ab; 287 293 288 294 if (MOMENTS) { 289 MxxAA += x*x*aa; 290 MyyAA += y*y*aa; 291 MxxBB += x*x*bb; 292 MyyBB += y*y*bb; 295 float winVal = (window) ? window->kernel[y][x] : 1.0; 296 MxxAA += winVal*x*x*aa; 297 MyyAA += winVal*y*y*aa; 298 MxxBB += winVal*x*x*bb; 299 MyyBB += winVal*y*y*bb; 293 300 } 294 301 } 295 302 } 296 303 304 // XXX does normSquare1,2 mess up the relative scaling? 305 // XXX no: normSquare1,2 is the sum of the flux^2 for the source 297 306 if (MOMENTS) { 298 307 MxxAA /= stamp->normSquare1 * PS_SQR(normValue); … … 304 313 // XXX this makes the Chisq portion independent of the normalization and star flux 305 314 // but may be mis-scaling between stars of different fluxes 315 # if (RENORM_BY_FLUX) 306 316 sumAA /= PS_SQR(stamp->normI2); 307 317 sumAB /= PS_SQR(stamp->normI2); 308 318 sumBB /= PS_SQR(stamp->normI2); 319 # endif 309 320 310 321 // fprintf (stderr, "i,j : %d %d : M(xx,yy)(AA,BB) : %f %f %f %f\n", i, j, MxxAA, MyyAA, MxxBB, MyyBB); … … 327 338 matrix->data.F64[iIndex][jIndex] += kernels->penalty * MxxAA * MOMENTS_PENALTY_SCALE; 328 339 matrix->data.F64[iIndex][jIndex] += kernels->penalty * MyyAA * MOMENTS_PENALTY_SCALE; 329 330 340 matrix->data.F64[jIndex][iIndex] += kernels->penalty * MxxAA * MOMENTS_PENALTY_SCALE; 331 341 matrix->data.F64[jIndex][iIndex] += kernels->penalty * MyyAA * MOMENTS_PENALTY_SCALE; … … 333 343 matrix->data.F64[iIndex + numParams][jIndex + numParams] += kernels->penalty * MxxBB * MOMENTS_PENALTY_SCALE; 334 344 matrix->data.F64[iIndex + numParams][jIndex + numParams] += kernels->penalty * MyyBB * MOMENTS_PENALTY_SCALE; 335 336 345 matrix->data.F64[jIndex + numParams][iIndex + numParams] += kernels->penalty * MxxBB * MOMENTS_PENALTY_SCALE; 337 346 matrix->data.F64[jIndex + numParams][iIndex + numParams] += kernels->penalty * MyyBB * MOMENTS_PENALTY_SCALE; … … 353 362 ab *= weight->kernel[y][x]; 354 363 } 355 if (window) { 364 // XXX NOTE: do NOT apply the window to the chisq portions of the calculation 365 if (false && window) { 356 366 ab *= window->kernel[y][x]; 357 367 } … … 362 372 // XXX this makes the Chisq portion independent of the normalization and star flux 363 373 // but may be mis-scaling between stars of different fluxes 374 # if (RENORM_BY_FLUX) 364 375 sumAB /= PS_SQR(stamp->normI2); 376 # endif 365 377 366 378 // Spatial variation of kernel coeffs … … 390 402 float i2 = image2->kernel[y][x]; 391 403 404 // XXX NOTE: clipping low S/N pixels does not seem to work very well 405 if (false && weight) { 406 float sn = (i1 + i2) / sqrt (weight->kernel[y][x]); 407 if (sn < 0.5) continue; 408 } 409 392 410 double ai2 = a * i2 * normValue; 393 411 double bi2 = b * i2; … … 395 413 double bi1 = b * i1 * normValue; 396 414 397 if (weight) { 398 float wtVal = weight->kernel[y][x]; 399 ai2 *= wtVal; 400 bi2 *= wtVal; 401 ai1 *= wtVal; 402 bi1 *= wtVal; 403 } 404 if (window) { 405 float wtVal = window->kernel[y][x]; 406 ai2 *= wtVal; 407 bi2 *= wtVal; 408 ai1 *= wtVal; 409 bi1 *= wtVal; 410 } 411 sumAI2 += ai2; 412 sumBI2 += bi2; 413 sumAI1 += ai1; 414 sumBI1 += bi1; 415 float wtVal = (weight) ? weight->kernel[y][x] : 1.0; 416 sumAI2 += wtVal*ai2; 417 sumBI2 += wtVal*bi2; 418 sumAI1 += wtVal*ai1; 419 sumBI1 += wtVal*bi1; 415 420 416 421 if (MOMENTS) { 417 MxxAI1 += x*x*ai1; 418 MyyAI1 += y*y*ai1; 419 MxxBI2 += x*x*bi2; 420 MyyBI2 += y*y*bi2; 422 float winVal = (window) ? window->kernel[y][x] : 1.0; 423 MxxAI1 += winVal*x*x*ai1; 424 MyyAI1 += winVal*y*y*ai1; 425 MxxBI2 += winVal*x*x*bi2; 426 MyyBI2 += winVal*y*y*bi2; 421 427 } 422 428 } … … 434 440 // XXX this makes the Chisq portion independent of the normalization and star flux 435 441 // but may be mis-scaling between stars of different fluxes 442 # if (RENORM_BY_FLUX) 436 443 sumAI1 /= PS_SQR(stamp->normI2); 437 444 sumBI1 /= PS_SQR(stamp->normI2); 438 445 sumAI2 /= PS_SQR(stamp->normI2); 439 446 sumBI2 /= PS_SQR(stamp->normI2); 447 # endif 440 448 441 449 // Spatial variation … … 799 807 pmSubtractionKernels *kernels = job->args->data[1]; // Kernels 800 808 int index = PS_SCALAR_VALUE(job->args->data[2], S32); // Stamp index 801 pmSubtractionEquationCalculationMode mode = PS_SCALAR_VALUE(job->args->data[3], S32); // calculation model 802 803 return pmSubtractionCalculateEquationStamp(stamps, kernels, index, mode); 804 } 805 806 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels, 807 int index, const pmSubtractionEquationCalculationMode mode) 809 810 return pmSubtractionCalculateEquationStamp(stamps, kernels, index); 811 } 812 813 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels, int index) 808 814 { 809 815 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); … … 832 838 psAssert(stamp->status == PM_SUBTRACTION_STAMP_CALCULATE, "We only operate on stamps with this state."); 833 839 834 // Generate convolutions: these are generated once and saved 835 if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) { 836 psError(psErrorCodeLast(), false, "Unable to convolve stamp %d.", index); 837 return NULL; 838 } 839 840 #ifdef TESTING 841 for (int j = 0; j < numKernels; j++) { 842 if (stamp->convolutions1) { 843 psString convName = NULL; 844 psStringAppend(&convName, "conv1_%03d_%03d.fits", index, j); 845 psFits *fits = psFitsOpen(convName, "w"); 846 psFree(convName); 847 psKernel *conv = stamp->convolutions1->data[j]; 848 psFitsWriteImage(fits, NULL, conv->image, 0, NULL); 849 psFitsClose(fits); 850 } 851 852 if (stamp->convolutions2) { 853 psString convName = NULL; 854 psStringAppend(&convName, "conv2_%03d_%03d.fits", index, j); 855 psFits *fits = psFitsOpen(convName, "w"); 856 psFree(convName); 857 psKernel *conv = stamp->convolutions2->data[j]; 858 psFitsWriteImage(fits, NULL, conv->image, 0, NULL); 859 psFitsClose(fits); 860 } 861 } 862 #endif 863 864 // XXX visualize the set of convolved stamps 865 866 psImage *polyValues = p_pmSubtractionPolynomial(NULL, spatialOrder, 867 stamp->xNorm, stamp->yNorm); // Polynomial terms 868 869 bool new = stamp->vector ? false : true; // Is this a new run? 840 psImage *polyValues = p_pmSubtractionPolynomial(NULL, spatialOrder, stamp->xNorm, stamp->yNorm); // Polynomial terms 841 842 // Is this a new run? Have we allocated the correct sized vector/matrix? 843 bool new = stamp->vector ? false : true; 844 if (!new && (stamp->vector->n != numParams)) { 845 psFree (stamp->vector); 846 psFree (stamp->matrix); 847 new = true; 848 } 849 870 850 if (new) { 871 851 stamp->matrix = psImageAlloc(numParams, numParams, PS_TYPE_F64); … … 940 920 } 941 921 942 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels, 943 const pmSubtractionEquationCalculationMode mode) 922 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels) 944 923 { 945 924 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); … … 952 931 for (int i = 0; i < stamps->num; i++) { 953 932 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 933 954 934 if (stamp->status != PM_SUBTRACTION_STAMP_CALCULATE) { 955 935 continue; … … 968 948 psArrayAdd(job->args, 1, (pmSubtractionKernels*)kernels); // Casting away const to put on array 969 949 PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32); 970 PS_ARRAY_ADD_SCALAR(job->args, mode, PS_TYPE_S32);971 950 if (!psThreadJobAddPending(job)) { 972 951 return false; 973 952 } 974 953 } else { 975 pmSubtractionCalculateEquationStamp(stamps, kernels, i , mode);954 pmSubtractionCalculateEquationStamp(stamps, kernels, i); 976 955 } 977 956 } … … 986 965 pmSubtractionVisualPlotLeastSquares(stamps); 987 966 988 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate equation: %f sec", 989 psTimerClear("pmSubtractionCalculateEquation")); 990 967 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate equation: %f sec", psTimerClear("pmSubtractionCalculateEquation")); 991 968 992 969 return true; … … 997 974 bool psFitsWriteImageSimple (char *filename, psImage *image, psMetadata *header); 998 975 999 psImage *p_pmSubSolve_wUt (psVector *w, psImage *U); 1000 psImage *p_pmSubSolve_VwUt (psImage *V, psImage *wUt); 1001 1002 bool p_pmSubSolve_SetWeights (psVector *wApply, psVector *w, psVector *wMask); 1003 1004 bool p_pmSubSolve_UtB (psVector **UtB, psImage *U, psVector *B); 1005 bool p_pmSubSolve_wUtB (psVector **wUtB, psVector *w, psVector *UtB); 1006 bool p_pmSubSolve_VwUtB (psVector **VwUtB, psImage *V, psVector *wUtB); 1007 1008 bool p_pmSubSolve_Ax (psVector **B, psImage *A, psVector *x); 1009 bool p_pmSubSolve_VdV (double *value, psVector *x, psVector *y); 1010 bool p_pmSubSolve_y2 (double *y2, pmSubtractionKernels *kernels, const pmSubtractionStampList *stamps); 1011 1012 psImage *p_pmSubSolve_Xvar (psImage *V, psVector *w); 1013 1014 double p_pmSubSolve_ChiSquare (pmSubtractionKernels *kernels, const pmSubtractionStampList *stamps); 1015 1016 bool pmSubtractionSolveEquation(pmSubtractionKernels *kernels, 1017 const pmSubtractionStampList *stamps, 1018 const pmSubtractionEquationCalculationMode mode) 976 bool pmSubtractionSolveEquation(pmSubtractionKernels *kernels, const pmSubtractionStampList *stamps) 1019 977 { 1020 978 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false); 1021 979 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 980 981 psTimerStart("pmSubtractionSolveEquation"); 1022 982 1023 983 // Check inputs … … 1041 1001 } 1042 1002 1003 if (stamp->vector->n != numParams) { 1004 fprintf (stderr, "mismatch length\n"); 1005 } 1043 1006 PS_ASSERT_VECTOR_NON_NULL(stamp->vector, false); 1044 1007 PS_ASSERT_VECTOR_SIZE(stamp->vector, (long)numParams, false); … … 1088 1051 #endif 1089 1052 1053 // XXX TEST : print the matrix & vector 1054 if (0) { 1055 for (int iy = 0; iy < sumMatrix->numRows; iy++) { 1056 for (int ix = 0; ix < sumMatrix->numCols; ix++) { 1057 fprintf (stderr, "%e ", sumMatrix->data.F64[iy][ix]); 1058 } 1059 fprintf (stderr, " : %e\n", sumVector->data.F64[iy]); 1060 } 1061 } 1062 1090 1063 psImage *invMatrix = NULL; 1091 1064 psVector *solution = NULL; // Solution to equation! … … 1096 1069 // solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN); 1097 1070 // SINGLE solution 1098 if (1) {1099 solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN);1100 invMatrix = psMatrixInvert(NULL, sumMatrix, NULL);1101 } else {1102 psVector *PERM = NULL;1103 psImage *LU = psMatrixLUDecomposition(NULL, &PERM, sumMatrix);1104 solution = psMatrixLUSolution(solution, LU, sumVector, PERM);1105 psFree (LU);1106 psFree (PERM);1107 }1108 1109 1071 # if (1) 1072 solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN); 1073 invMatrix = psMatrixInvert(NULL, sumMatrix, NULL); 1074 # endif 1075 # if (0) 1076 psMatrixLUSolve(sumMatrixLU, sumVector); 1077 solution = psMemIncrRefCounter(sumVector); 1078 invMatrix = psMemIncrRefCounter(sumMatrix); 1079 # endif 1080 # if (0) 1081 psMatrixGJSolve(sumMatrix, sumVector); 1082 invMatrix = psMemIncrRefCounter(sumMatrix); 1083 solution = psMemIncrRefCounter(sumVector); 1084 # endif 1085 1086 # if (0) 1110 1087 for (int i = 0; i < solution->n; 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]));1088 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "Single solution %d: %lf +/- %lf\n", i, solution->data.F64[i], sqrt(fabs(invMatrix->data.F64[i][i]))); 1112 1089 } 1113 1090 # endif 1114 1091 1115 if (!kernels->solution1) { 1116 kernels->solution1 = psVectorAlloc(sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 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); 1120 } 1092 // ensure we have a solution vector of the right size 1093 kernels->solution1 = psVectorRecycle(kernels->solution1, sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 1094 kernels->solution1err = psVectorRecycle(kernels->solution1err, sumVector->n + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 1095 psVectorInit(kernels->solution1, 0.0); 1096 psVectorInit(kernels->solution1err, 0.0); 1121 1097 1122 1098 int numKernels = kernels->num; 1123 1099 int spatialOrder = kernels->spatialOrder; // Order of spatial variation 1124 1100 int numPoly = PM_SUBTRACTION_POLYTERMS(spatialOrder); // Number of polynomial terms 1101 1125 1102 for (int i = 0; i < numKernels * numPoly; i++) { 1126 1103 kernels->solution1->data.F64[i] = solution->data.F64[i]; … … 1180 1157 } 1181 1158 1159 // XXX TEST : print the matrix & vector 1160 if (0) { 1161 for (int iy = 0; iy < sumMatrix->numRows; iy++) { 1162 for (int ix = 0; ix < sumMatrix->numCols; ix++) { 1163 fprintf (stderr, "%e ", sumMatrix->data.F64[iy][ix]); 1164 } 1165 fprintf (stderr, " : %e\n", sumVector->data.F64[iy]); 1166 } 1167 } 1168 1182 1169 psImage *invMatrix = NULL; 1183 1170 psVector *solution = NULL; // Solution to equation! … … 1187 1174 // DUAL solution 1188 1175 # if (1) 1189 solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, 1e-7);1176 solution = psMatrixSolveSVD(solution, sumMatrix, sumVector, NAN); 1190 1177 invMatrix = psMatrixInvert(NULL, sumMatrix, NULL); 1191 1178 # endif 1192 1179 # if (0) 1193 1180 psMatrixLUSolve(sumMatrix, sumVector); 1194 solution = sumVector;1195 invMatrix = sumMatrix;1181 solution = psMemIncrRefCounter(sumVector); 1182 invMatrix = psMemIncrRefCounter(sumMatrix); 1196 1183 # endif 1197 1184 1198 #if ( 1)1185 #if (0) 1199 1186 for (int i = 0; i < solution->n; i++) { 1200 1187 fprintf(stderr, "Dual solution %d: %lf +/- %lf\n", i, solution->data.F64[i], sqrt(invMatrix->data.F64[i][i])); … … 1202 1189 #endif 1203 1190 1204 if (!kernels->solution1) { 1205 kernels->solution1 = psVectorAlloc(numSolution1 + 2, PS_TYPE_F64); 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); 1209 } 1210 if (!kernels->solution2) { 1211 kernels->solution2 = psVectorAlloc(numSolution2, PS_TYPE_F64); 1212 psVectorInit (kernels->solution2, 0.0); 1213 kernels->solution2err = psVectorAlloc(numSolution2, PS_TYPE_F64); 1214 psVectorInit(kernels->solution2err, 0.0); 1215 } 1191 // XXX TEST: manually set the coeffs to a desired solution 1192 // solution->data.F64[0] = +1.826; 1193 // solution->data.F64[1] = -0.115; 1194 // solution->data.F64[2] = 0.0; 1195 // solution->data.F64[3] = 0.0; 1196 1197 // ensure we have solution vectors of the right size 1198 kernels->solution1 = psVectorRecycle(kernels->solution1, numSolution1 + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 1199 kernels->solution1err = psVectorRecycle(kernels->solution1err, numSolution1 + 2, PS_TYPE_F64); // 1 for norm, 1 for bg 1200 kernels->solution2 = psVectorRecycle(kernels->solution2, numSolution2, PS_TYPE_F64); // 1 for norm, 1 for bg 1201 kernels->solution2err = psVectorRecycle(kernels->solution2err, numSolution2, PS_TYPE_F64); // 1 for norm, 1 for bg 1202 1203 psVectorInit(kernels->solution1, 0.0); 1204 psVectorInit(kernels->solution1err, 0.0); 1205 psVectorInit(kernels->solution2, 0.0); 1206 psVectorInit(kernels->solution2err, 0.0); 1216 1207 1217 1208 // for DUAL convolution analysis, we apply the normalization to I1 as follows: … … 1259 1250 } 1260 1251 } 1252 1253 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Solve equation: %f sec", psTimerClear("pmSubtractionSolveEquation")); 1261 1254 1262 1255 // pmSubtractionVisualPlotLeastSquares((pmSubtractionStampList *) stamps); //casting away const … … 1311 1304 1312 1305 // 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) { 1306 bool pmSubtractionChisqStats(psVector *fluxesVector, psVector *chisqVector, psVector *momentVector, psVector *stampMask, psKernel *convolved1, psKernel *convolved2, psKernel *residual, psKernel *weight, psKernel *window) { 1307 1308 # ifndef USE_WEIGHT 1309 psAssert(weight == NULL, "impossible!"); 1310 # endif 1311 # ifndef USE_WINDOW 1312 psAssert(window == NULL, "impossible!"); 1313 # endif 1314 1314 1315 1315 int npix = 0; … … 1319 1319 for (int y = residual->yMin; y <= residual->yMax; y++) { 1320 1320 for (int x = residual->xMin; x <= residual->xMax; x++) { 1321 chisq += PS_SQR(residual->kernel[y][x]); 1321 float value = PS_SQR(residual->kernel[y][x]); 1322 if (weight) { 1323 value *= weight->kernel[y][x]; 1324 } 1325 // XXX NOTE: do NOT apply the window to the chisq portions of the calculation 1326 if (false && window) { 1327 value *= window->kernel[y][x]; 1328 } 1329 chisq += value; 1322 1330 npix ++; 1323 1331 } … … 1345 1353 value2 = PS_SQR(value1); 1346 1354 1347 if (weight) { 1355 if (window) { 1356 value1 *= window->kernel[y][x]; 1357 value2 *= window->kernel[y][x]; 1358 } 1359 1360 fluxC1 += value1; 1361 flux2 += value2; 1362 fluxX += x * value2; 1363 fluxY += y * value2; 1364 // fluxX2 += PS_SQR(x) * value2; 1365 // fluxY2 += PS_SQR(y) * value2; 1366 fluxX2 += PS_SQR(x) * value1; 1367 fluxY2 += PS_SQR(y) * value1; 1368 } 1369 } 1370 // float Mx = fluxX / flux2; 1371 // float My = fluxY / flux2; 1372 // float Mxx = fluxX2 / flux2; 1373 // float Myy = fluxY2 / flux2; 1374 float Mxx = fluxX2 / fluxC1; 1375 float Myy = fluxY2 / fluxC1; 1376 1377 // 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); 1378 moment += Mxx + Myy; 1379 } 1380 1381 // get the moments from convolved1 1382 if (convolved2) { 1383 for (int y = residual->yMin; y <= residual->yMax; y++) { 1384 for (int x = residual->xMin; x <= residual->xMax; x++) { 1385 value1 = convolved2->kernel[y][x]; 1386 value2 = PS_SQR(value1); 1387 1388 // XXX NOTE: do NOT apply the weight to the moments calculation 1389 if (false && weight) { 1348 1390 value2 *= weight->kernel[y][x]; 1349 1391 } … … 1353 1395 } 1354 1396 1355 fluxC 1+= value1;1397 fluxC2 += value1; 1356 1398 flux2 += value2; 1357 1399 fluxX += x * value2; 1358 1400 fluxY += y * value2; 1359 fluxX2 += PS_SQR(x) * value2; 1360 fluxY2 += PS_SQR(y) * value2; 1401 // fluxX2 += PS_SQR(x) * value2; 1402 // fluxY2 += PS_SQR(y) * value2; 1403 fluxX2 += PS_SQR(x) * value1; 1404 fluxY2 += PS_SQR(y) * value1; 1361 1405 } 1362 1406 } 1363 1407 // float Mx = fluxX / flux2; 1364 1408 // 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; 1409 // float Mxx = fluxX2 / flux2; 1410 // float Myy = fluxY2 / flux2; 1411 float Mxx = fluxX2 / fluxC2; 1412 float Myy = fluxY2 / fluxC2; 1399 1413 1400 1414 // 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); … … 1410 1424 psVectorAppend(momentVector, moment); 1411 1425 psVectorAppend(fluxesVector, flux); 1426 psVectorAppend(stampMask, 0); 1412 1427 return true; 1413 1428 } 1414 1429 1415 // typedef struct { 1416 // float moment; 1417 // float chisq; 1418 // } diffStat; 1419 1420 bool pmSubtractionCalculateChisqAndMoments(pmSubtractionStampList *stamps, 1430 bool pmSubtractionCalculateChisqAndMoments(pmSubtractionQuality **bestMatch, 1431 pmSubtractionStampList *stamps, 1421 1432 pmSubtractionKernels *kernels) 1422 1433 { … … 1425 1436 PM_ASSERT_SUBTRACTION_KERNELS_SOLUTION(kernels, NULL); 1426 1437 1438 psTimerStart("pmSubtractionCalculateChisqAndMoments"); 1439 1440 // XXX need to save these somewhere 1427 1441 psVector *fluxes = psVectorAllocEmpty(stamps->num, PS_TYPE_F32); 1428 1442 psVector *chisq = psVectorAllocEmpty(stamps->num, PS_TYPE_F32); 1429 1443 psVector *moments = psVectorAllocEmpty(stamps->num, PS_TYPE_F32); 1444 psVector *stampMask = psVectorAllocEmpty(stamps->num, PS_TYPE_VECTOR_MASK); 1430 1445 1431 1446 int footprint = stamps->footprint; // Half-size of stamps … … 1434 1449 psImage *polyValues = NULL; // Polynomial values 1435 1450 1451 // storage for the image (convolved2 is not used in SINGLE mode) 1436 1452 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 1453 psKernel *convolved1 = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image 1440 1454 psKernel *convolved2 = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image 1441 1455 1456 int nGood = 0; 1442 1457 for (int i = 0; i < stamps->num; i++) { 1443 1458 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // The stamp of interest 1444 1459 if (stamp->status != PM_SUBTRACTION_STAMP_USED) { 1460 // mark this stamp as unused (note that we have to append NANs to the other vectors to keep the lengths in sync) 1461 psVectorAppend(moments, NAN); 1462 psVectorAppend(fluxes, NAN); 1463 psVectorAppend(chisq, NAN); 1464 psVectorAppend(stampMask, 0x01); 1445 1465 continue; 1446 1466 } 1467 nGood ++; 1447 1468 1448 1469 // Calculate coefficients of the kernel basis functions … … 1454 1475 psImageInit(residual->image, 0.0); 1455 1476 1456 psKernel *weight = NULL;1457 psKernel *window = NULL;1458 1477 psKernel *weight = NULL; 1478 psKernel *window = NULL; 1479 1459 1480 #ifdef USE_WEIGHT 1460 1481 weight = stamp->weight; … … 1511 1532 } 1512 1533 // 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);1534 pmSubtractionChisqStats(fluxes, chisq, moments, stampMask, convolved1, NULL, residual, weight, window); 1514 1535 1515 1536 } else { … … 1555 1576 } 1556 1577 1557 pmSubtractionChisqStats(fluxes, chisq, moments, convolved1, convolved2, residual, weight, window); 1558 } 1559 } 1560 1561 pmSubtractionVisualPlotChisqAndMoments(fluxes, chisq, moments); 1578 pmSubtractionChisqStats(fluxes, chisq, moments, stampMask, convolved1, convolved2, residual, weight, window); 1579 } 1580 } 1562 1581 1563 1582 // find the mean chisq and mean moment 1564 1583 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN); 1565 psVectorStats (stats, chisq, NULL, NULL, 0);1584 psVectorStats (stats, chisq, NULL, stampMask, 0xff); 1566 1585 float chisqValue = stats->sampleMean; 1567 1586 1568 1587 psStatsInit(stats); 1569 psVectorStats (stats, moments, NULL, NULL, 0);1588 psVectorStats (stats, moments, NULL, stampMask, 0xff); 1570 1589 float momentValue = stats->sampleMean; 1571 1590 1572 fprintf (stderr, "chisq: %f, moment: %f\n", chisqValue, momentValue); 1591 // XXX this is probably wrong : I want to score against higher moments **compared with the raw momements** 1592 // score : chisq * dMoments * modeFactor 1593 float modeFactor = kernels->mode == PM_SUBTRACTION_MODE_DUAL ? 2.0 : 1.0; 1594 float orderFactor = 0.5*(kernels->spatialOrder + 1) * (kernels->spatialOrder + 2); 1595 float score = chisqValue * momentValue * modeFactor * orderFactor; 1596 1597 fprintf (stderr, "chisq: %f, moment: %f, score: %f\n", chisqValue, momentValue, score); 1598 1599 // save this result if it is the first or the best (skip if bestMatch is NULL) 1600 if (bestMatch) { 1601 pmSubtractionQuality *match = *bestMatch; 1602 bool keep = false; 1603 if (match == NULL) { 1604 *bestMatch = match = pmSubtractionQualityAlloc(); 1605 keep = true; 1606 } else { 1607 if (score < match->score) { 1608 psFree(match->fluxes); 1609 psFree(match->chisq); 1610 psFree(match->moments); 1611 psFree(match->stampMask); 1612 keep = true; 1613 } 1614 } 1615 if (keep) { 1616 fprintf (stderr, "keeping order: %d, mode: %d, score: %f\n", kernels->spatialOrder, kernels->mode, score); 1617 match->score = score; 1618 match->spatialOrder = kernels->spatialOrder; 1619 match->mode = kernels->mode; 1620 match->nGood = nGood; 1621 match->fluxes = psMemIncrRefCounter(fluxes); 1622 match->chisq = psMemIncrRefCounter(chisq); 1623 match->moments = psMemIncrRefCounter(moments); 1624 match->stampMask = psMemIncrRefCounter(stampMask); 1625 } 1626 } 1627 1628 pmSubtractionVisualPlotChisqAndMoments(fluxes, chisq, moments); 1573 1629 1574 1630 psFree(stats); … … 1576 1632 psFree(fluxes); 1577 1633 psFree(moments); 1634 psFree(stampMask); 1578 1635 1579 1636 psFree(residual); … … 1582 1639 psFree(polyValues); 1583 1640 1641 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate Chisq and Moments: %f sec", psTimerClear("pmSubtractionCalculateChisqAndMoments")); 1642 1584 1643 return true; 1585 1644 } 1586 1645 1587 psVector *pmSubtractionCalculateDeviations(pmSubtractionStampList *stamps, 1588 pmSubtractionKernels *kernels)1646 // XXX for now, let's not use this, and let's instead just use values from pmSubtractionCalculateChisqAndMoments 1647 psVector *pmSubtractionCalculateDeviations(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels) 1589 1648 { 1590 1649 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, NULL); 1591 1650 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, NULL); 1592 1651 PM_ASSERT_SUBTRACTION_KERNELS_SOLUTION(kernels, NULL); 1652 1653 psTimerStart("pmSubtractionCalculateDeviations"); 1593 1654 1594 1655 psVector *deviations = psVectorAlloc(stamps->num, PS_TYPE_F32); // Mean deviation for stamps … … 1600 1661 psImage *polyValues = NULL; // Polynomial values 1601 1662 psKernel *residual = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image 1602 1603 // set up holding images for the visualization1604 pmSubtractionVisualShowFitInit (stamps);1605 1663 1606 1664 psVector *fResSigma = psVectorAllocEmpty(stamps->num, PS_TYPE_F32); … … 1703 1761 } 1704 1762 1705 // XXX visualize the target, source, convolution and residual1706 pmSubtractionVisualShowFitAddStamp (target, source, residual, background, norm, i);1707 1708 1763 for (int y = - footprint; y <= footprint; y++) { 1709 1764 for (int x = - footprint; x <= footprint; x++) { … … 1740 1795 } 1741 1796 1742 // XXX visualize the target, source, convolution and residual1743 pmSubtractionVisualShowFitAddStamp (image2, image1, residual, background, norm, i);1744 1745 1797 for (int y = - footprint; y <= footprint; y++) { 1746 1798 for (int x = - footprint; x <= footprint; x++) { … … 1757 1809 } 1758 1810 1811 double flux = 0.0; 1759 1812 double deviation = 0.0; // Sum of differences 1760 1813 for (int y = - footprint; y <= footprint; y++) { … … 1762 1815 double dev = PS_SQR(residual->kernel[y][x]) * weight->kernel[y][x]; 1763 1816 deviation += dev; 1764 #ifdef TESTING 1765 residual->kernel[y][x] = dev; 1766 #endif 1817 flux += stamp->image1->kernel[y][x] + stamp->image2->kernel[y][x]; 1767 1818 } 1768 1819 } 1769 1820 deviations->data.F32[i] = devNorm * deviation; 1770 psTrace("psModules.imcombine", 5, "Deviation for stamp %d (%d,%d):%f\n",1771 i, (int)(stamp->x - 0.5), (int)(stamp->y - 0.5), deviations->data.F32[i] );1821 psTrace("psModules.imcombine", 5, "Deviation and Flux for stamp %d (%d,%d): %f %f\n", 1822 i, (int)(stamp->x - 0.5), (int)(stamp->y - 0.5), deviations->data.F32[i], flux); 1772 1823 psStringAppend(&log, "Stamp %d (%d,%d): %f\n", 1773 1824 i, (int)(stamp->x - 0.5), (int)(stamp->y - 0.5), deviations->data.F32[i]); 1774 1825 if (!isfinite(deviations->data.F32[i])) { 1775 1826 stamp->status = PM_SUBTRACTION_STAMP_REJECTED; 1776 psTrace("psModules.imcombine", 5, 1777 "Rejecting stamp %d (%d,%d) because of non-finite deviation\n", 1778 i, (int)(stamp->x - 0.5), (int)(stamp->y - 0.5)); 1827 psTrace("psModules.imcombine", 5, "Rejecting stamp %d (%d,%d) because of non-finite deviation\n", i, (int)(stamp->x - 0.5), (int)(stamp->y - 0.5)); 1779 1828 continue; 1780 1829 } 1781 1782 #ifdef TESTING1783 {1784 psString filename = NULL;1785 psStringAppend(&filename, "resid_%03d.fits", i);1786 psFits *fits = psFitsOpen(filename, "w");1787 psFree(filename);1788 psFitsWriteImage(fits, NULL, residual->image, 0, NULL);1789 psFitsClose(fits);1790 }1791 if (stamp->image1) {1792 psString filename = NULL;1793 psStringAppend(&filename, "stamp_image1_%03d.fits", i);1794 psFits *fits = psFitsOpen(filename, "w");1795 psFree(filename);1796 psFitsWriteImage(fits, NULL, stamp->image1->image, 0, NULL);1797 psFitsClose(fits);1798 }1799 if (stamp->image2) {1800 psString filename = NULL;1801 psStringAppend(&filename, "stamp_image2_%03d.fits", i);1802 psFits *fits = psFitsOpen(filename, "w");1803 psFree(filename);1804 psFitsWriteImage(fits, NULL, stamp->image2->image, 0, NULL);1805 psFitsClose(fits);1806 }1807 if (stamp->weight) {1808 psString filename = NULL;1809 psStringAppend(&filename, "stamp_weight_%03d.fits", i);1810 psFits *fits = psFitsOpen(filename, "w");1811 psFree(filename);1812 psFitsWriteImage(fits, NULL, stamp->weight->image, 0, NULL);1813 psFitsClose(fits);1814 }1815 #endif1816 1817 1830 } 1818 1831 … … 1829 1842 psLogMsg("psModules.imcombine", PS_LOG_INFO, "normalization: %f, background: %f", norm, background); 1830 1843 1831 pmSubtractionVisualShowFit(norm);1832 pmSubtractionVisualPlotFit(kernels);1833 1834 1844 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 1835 1845 psVectorStats (stats, fResSigma, NULL, NULL, 0); … … 1862 1872 psFree(polyValues); 1863 1873 1874 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Calculate Deviations: %f sec", psTimerClear("pmSubtractionCalculateDeviations")); 1875 1864 1876 return deviations; 1865 }1866 1867 // we are supplied U, not Ut; w represents a diagonal matrix (also, we apply 1/w instead of w)1868 psImage *p_pmSubSolve_wUt (psVector *w, psImage *U) {1869 1870 psAssert (w->n == U->numCols, "w and U dimensions do not match");1871 1872 // wUt has dimensions transposed relative to Ut.1873 psImage *wUt = psImageAlloc (U->numRows, U->numCols, PS_TYPE_F64);1874 psImageInit (wUt, 0.0);1875 1876 for (int i = 0; i < wUt->numCols; i++) {1877 for (int j = 0; j < wUt->numRows; j++) {1878 if (!isfinite(w->data.F64[j])) continue;1879 if (w->data.F64[j] == 0.0) continue;1880 wUt->data.F64[j][i] = U->data.F64[i][j] / w->data.F64[j];1881 }1882 }1883 return wUt;1884 }1885 1886 // XXX this is just standard matrix multiplication: use psMatrixMultiply?1887 psImage *p_pmSubSolve_VwUt (psImage *V, psImage *wUt) {1888 1889 psAssert (V->numCols == wUt->numRows, "matrix dimensions do not match");1890 1891 psImage *Ainv = psImageAlloc (wUt->numCols, V->numRows, PS_TYPE_F64);1892 1893 for (int i = 0; i < Ainv->numCols; i++) {1894 for (int j = 0; j < Ainv->numRows; j++) {1895 double sum = 0.0;1896 for (int k = 0; k < V->numCols; k++) {1897 sum += V->data.F64[j][k] * wUt->data.F64[k][i];1898 }1899 Ainv->data.F64[j][i] = sum;1900 }1901 }1902 return Ainv;1903 }1904 1905 // we are supplied U, not Ut1906 bool p_pmSubSolve_UtB (psVector **UtB, psImage *U, psVector *B) {1907 1908 psAssert (U->numRows == B->n, "U and B dimensions do not match");1909 1910 UtB[0] = psVectorRecycle (UtB[0], U->numCols, PS_TYPE_F64);1911 1912 for (int i = 0; i < U->numCols; i++) {1913 double sum = 0.0;1914 for (int j = 0; j < U->numRows; j++) {1915 sum += B->data.F64[j] * U->data.F64[j][i];1916 }1917 UtB[0]->data.F64[i] = sum;1918 }1919 return true;1920 }1921 1922 // w is diagonal1923 bool p_pmSubSolve_wUtB (psVector **wUtB, psVector *w, psVector *UtB) {1924 1925 psAssert (w->n == UtB->n, "w and UtB dimensions do not match");1926 1927 // wUt has dimensions transposed relative to Ut.1928 wUtB[0] = psVectorRecycle (wUtB[0], w->n, PS_TYPE_F64);1929 psVectorInit (wUtB[0], 0.0);1930 1931 for (int i = 0; i < w->n; i++) {1932 if (!isfinite(w->data.F64[i])) continue;1933 if (w->data.F64[i] == 0.0) continue;1934 wUtB[0]->data.F64[i] = UtB->data.F64[i] / w->data.F64[i];1935 }1936 return true;1937 }1938 1939 // this is basically matrix * vector1940 bool p_pmSubSolve_VwUtB (psVector **VwUtB, psImage *V, psVector *wUtB) {1941 1942 psAssert (V->numCols == wUtB->n, "V and wUtB dimensions do not match");1943 1944 VwUtB[0] = psVectorRecycle (*VwUtB, V->numRows, PS_TYPE_F64);1945 1946 for (int j = 0; j < V->numRows; j++) {1947 double sum = 0.0;1948 for (int i = 0; i < V->numCols; i++) {1949 sum += V->data.F64[j][i] * wUtB->data.F64[i];1950 }1951 VwUtB[0]->data.F64[j] = sum;1952 }1953 return true;1954 }1955 1956 // this is basically matrix * vector1957 bool p_pmSubSolve_Ax (psVector **B, psImage *A, psVector *x) {1958 1959 psAssert (A->numCols == x->n, "A and x dimensions do not match");1960 1961 B[0] = psVectorRecycle (*B, A->numRows, PS_TYPE_F64);1962 1963 for (int j = 0; j < A->numRows; j++) {1964 double sum = 0.0;1965 for (int i = 0; i < A->numCols; i++) {1966 sum += A->data.F64[j][i] * x->data.F64[i];1967 }1968 B[0]->data.F64[j] = sum;1969 }1970 return true;1971 }1972 1973 // this is basically Vector * vector1974 bool p_pmSubSolve_VdV (double *value, psVector *x, psVector *y) {1975 1976 psAssert (x->n == y->n, "x and y dimensions do not match");1977 1978 double sum = 0.0;1979 for (int i = 0; i < x->n; i++) {1980 sum += x->data.F64[i] * y->data.F64[i];1981 }1982 *value = sum;1983 return true;1984 }1985 1986 bool p_pmSubSolve_y2 (double *y2, pmSubtractionKernels *kernels, const pmSubtractionStampList *stamps) {1987 1988 int footprint = stamps->footprint; // Half-size of stamps1989 1990 double sum = 0.0;1991 for (int i = 0; i < stamps->num; i++) {1992 1993 pmSubtractionStamp *stamp = stamps->stamps->data[i];1994 if (stamp->status != PM_SUBTRACTION_STAMP_USED) continue;1995 1996 psKernel *weight = NULL;1997 psKernel *window = NULL;1998 psKernel *input = NULL;1999 2000 #ifdef USE_WEIGHT2001 weight = stamp->weight;2002 #endif2003 #ifdef USE_WINDOW2004 window = stamps->window;2005 #endif2006 2007 switch (kernels->mode) {2008 // MODE_1 : convolve image 1 to match image 2 (and vice versa)2009 case PM_SUBTRACTION_MODE_1:2010 input = stamp->image2;2011 break;2012 case PM_SUBTRACTION_MODE_2:2013 input = stamp->image1;2014 break;2015 default:2016 psAbort ("programming error");2017 }2018 2019 for (int y = - footprint; y <= footprint; y++) {2020 for (int x = - footprint; x <= footprint; x++) {2021 double in = input->kernel[y][x];2022 double value = in*in;2023 if (weight) {2024 float wtVal = weight->kernel[y][x];2025 value *= wtVal;2026 }2027 if (window) {2028 float winVal = window->kernel[y][x];2029 value *= winVal;2030 }2031 sum += value;2032 }2033 }2034 }2035 *y2 = sum;2036 return true;2037 }2038 2039 double p_pmSubSolve_ChiSquare (pmSubtractionKernels *kernels, const pmSubtractionStampList *stamps) {2040 2041 int footprint = stamps->footprint; // Half-size of stamps2042 int numKernels = kernels->num; // Number of kernels2043 2044 double sum = 0.0;2045 2046 psKernel *residual = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Residual image2047 psImageInit(residual->image, 0.0);2048 2049 psImage *polyValues = NULL; // Polynomial values2050 2051 for (int i = 0; i < stamps->num; i++) {2052 2053 pmSubtractionStamp *stamp = stamps->stamps->data[i];2054 if (stamp->status != PM_SUBTRACTION_STAMP_USED) continue;2055 2056 psKernel *weight = NULL;2057 psKernel *window = NULL;2058 psKernel *target = NULL;2059 psKernel *source = NULL;2060 2061 psArray *convolutions = NULL;2062 2063 #ifdef USE_WEIGHT2064 weight = stamp->weight;2065 #endif2066 #ifdef USE_WINDOW2067 window = stamps->window;2068 #endif2069 2070 switch (kernels->mode) {2071 // MODE_1 : convolve image 1 to match image 2 (and vice versa)2072 case PM_SUBTRACTION_MODE_1:2073 target = stamp->image2;2074 source = stamp->image1;2075 convolutions = stamp->convolutions1;2076 break;2077 case PM_SUBTRACTION_MODE_2:2078 target = stamp->image1;2079 source = stamp->image2;2080 convolutions = stamp->convolutions2;2081 break;2082 default:2083 psAbort ("programming error");2084 }2085 2086 // Calculate coefficients of the kernel basis functions2087 polyValues = p_pmSubtractionPolynomial(polyValues, kernels->spatialOrder, stamp->xNorm, stamp->yNorm);2088 double norm = p_pmSubtractionSolutionNorm(kernels); // Normalisation2089 double background = p_pmSubtractionSolutionBackground(kernels, polyValues);// Difference in background2090 2091 psImageInit(residual->image, 0.0);2092 for (int j = 0; j < numKernels; j++) {2093 psKernel *convolution = convolutions->data[j]; // Convolution2094 double coefficient = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, false); // Coefficient2095 for (int y = - footprint; y <= footprint; y++) {2096 for (int x = - footprint; x <= footprint; x++) {2097 residual->kernel[y][x] -= convolution->kernel[y][x] * coefficient;2098 }2099 }2100 }2101 2102 for (int y = - footprint; y <= footprint; y++) {2103 for (int x = - footprint; x <= footprint; x++) {2104 double resid = target->kernel[y][x] - background - source->kernel[y][x] * norm + residual->kernel[y][x];2105 double value = PS_SQR(resid);2106 if (weight) {2107 float wtVal = weight->kernel[y][x];2108 value *= wtVal;2109 }2110 if (window) {2111 float winVal = window->kernel[y][x];2112 value *= winVal;2113 }2114 sum += value;2115 }2116 }2117 }2118 psFree (polyValues);2119 psFree (residual);2120 2121 return sum;2122 }2123 2124 bool p_pmSubSolve_SetWeights (psVector *wApply, psVector *w, psVector *wMask) {2125 2126 for (int i = 0; i < w->n; i++) {2127 wApply->data.F64[i] = wMask->data.U8[i] ? 0.0 : w->data.F64[i];2128 }2129 return true;2130 }2131 2132 // we are supplied V and w; w represents a diagonal matrix (also, we apply 1/w instead of w)2133 psImage *p_pmSubSolve_Xvar (psImage *V, psVector *w) {2134 2135 psAssert (w->n == V->numCols, "w and U dimensions do not match");2136 2137 psImage *Vn = psImageAlloc (V->numCols, V->numRows, PS_TYPE_F64);2138 psImageInit (Vn, 0.0);2139 2140 // generate Vn = V * w^{-1}2141 for (int j = 0; j < Vn->numRows; j++) {2142 for (int i = 0; i < Vn->numCols; i++) {2143 if (!isfinite(w->data.F64[i])) continue;2144 if (w->data.F64[i] == 0.0) continue;2145 Vn->data.F64[j][i] = V->data.F64[j][i] / w->data.F64[i];2146 }2147 }2148 2149 psImage *Xvar = psImageAlloc (V->numCols, V->numRows, PS_TYPE_F64);2150 psImageInit (Xvar, 0.0);2151 2152 // generate Xvar = Vn * Vn^T2153 for (int j = 0; j < Vn->numRows; j++) {2154 for (int i = 0; i < Vn->numCols; i++) {2155 double sum = 0.0;2156 for (int k = 0; k < Vn->numCols; k++) {2157 sum += Vn->data.F64[k][i]*Vn->data.F64[k][j];2158 }2159 Xvar->data.F64[j][i] = sum;2160 }2161 }2162 return Xvar;2163 1877 } 2164 1878 … … 2166 1880 // of the elements of an image A(x,y) = A->data.F64[y][x] = A_x,y, a matrix 2167 1881 // multiplication is: A_k,j * B_i,k = C_i,j 2168 2169 1882 2170 1883 bool psFitsWriteImageSimple (char *filename, psImage *image, psMetadata *header) { -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.h
r30266 r30289 4 4 #include "pmSubtractionStamps.h" 5 5 #include "pmSubtractionKernels.h" 6 #include "pmSubtraction.h" 6 7 7 typedef enum {8 PM_SUBTRACTION_EQUATION_NONE = 0x00,9 PM_SUBTRACTION_EQUATION_NORM = 0x01,10 PM_SUBTRACTION_EQUATION_BG = 0x02,11 PM_SUBTRACTION_EQUATION_KERNELS = 0x04,12 PM_SUBTRACTION_EQUATION_ALL = 0x07, // value should be NORM | BG | KERNELS13 } pmSubtractionEquationCalculationMode;8 // typedef enum { 9 // PM_SUBTRACTION_EQUATION_NONE = 0x00, 10 // PM_SUBTRACTION_EQUATION_NORM = 0x01, 11 // PM_SUBTRACTION_EQUATION_BG = 0x02, 12 // PM_SUBTRACTION_EQUATION_KERNELS = 0x04, 13 // PM_SUBTRACTION_EQUATION_ALL = 0x07, // value should be NORM | BG | KERNELS 14 // } pmSubtractionEquationCalculationMode; 14 15 15 16 /// Execute a thread job to calculate the least-squares equation for a stamp … … 20 21 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, ///< Stamps 21 22 pmSubtractionKernels *kernels, ///< Kernel parameters 22 int index, ///< Index of stamp 23 const pmSubtractionEquationCalculationMode mode 23 int index ///< Index of stamp 24 24 ); 25 25 26 26 /// Calculate the least-squares equation to match the image quality 27 27 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, ///< Stamps 28 pmSubtractionKernels *kernels, ///< Kernel parameters 29 const pmSubtractionEquationCalculationMode mode 28 pmSubtractionKernels *kernels ///< Kernel parameters 30 29 ); 31 30 32 31 /// Solve the least-squares equation to match the image quality 33 32 bool pmSubtractionSolveEquation(pmSubtractionKernels *kernels, ///< Kernel parameters 34 const pmSubtractionStampList *stamps, ///< Stamps 35 const pmSubtractionEquationCalculationMode mode 33 const pmSubtractionStampList *stamps ///< Stamps 36 34 ); 37 35 … … 92 90 bool pmSubtractionCalculateMomentsKernel(double *Mxx, double *Myy, psKernel *image, int footprint, int window); 93 91 94 bool pmSubtractionChisqStats(psVector *fluxesVector, psVector *chisqVector, psVector *momentVector, ps Kernel *convolved1, psKernel *convolved2, psKernel *residual, psKernel *weight, psKernel *window);92 bool pmSubtractionChisqStats(psVector *fluxesVector, psVector *chisqVector, psVector *momentVector, psVector *stampMask, psKernel *convolved1, psKernel *convolved2, psKernel *residual, psKernel *weight, psKernel *window); 95 93 96 bool pmSubtractionCalculateChisqAndMoments(pmSubtractionStampList *stamps, 97 pmSubtractionKernels *kernels); 98 94 bool pmSubtractionCalculateChisqAndMoments(pmSubtractionQuality **bestMatch, pmSubtractionStampList *stamps, pmSubtractionKernels *kernels); 99 95 #endif -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionStamps.c
r30266 r30289 122 122 if ((image1 && image1->data.F32[y][x] < thresh1) || 123 123 (image2 && image2->data.F32[y][x] < thresh2)) { 124 // fprintf (stderr, "%f,%f : thresh\n", xRaw, yRaw); 124 125 continue; 125 126 } … … 429 430 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, 430 431 normFrac, sysErr, skyErr); 432 } 433 434 // XXX TEST : dump all stars in the stamps here 435 if (0) { 436 FILE *f = fopen ("stamp.dat", "w"); 437 for (int i = 0; i < stamps->num; i++) { 438 psVector *xList = stamps->x->data[i]; 439 psVector *yList = stamps->y->data[i]; // Coordinate lists 440 psVector *fluxList = stamps->flux->data[i]; // List of stamp fluxes 441 442 for (int j = 0; j < xList->n; j++) { 443 fprintf (f, "%d %d %f %f %f\n", i, j, xList->data.F32[j], yList->data.F32[j], fluxList->data.F32[j]); 444 } 445 } 446 fclose (f); 431 447 } 432 448 … … 636 652 } 637 653 654 int nTotal = 0; 655 638 656 // Sort the list by flux, with the brightest last 639 657 for (int i = 0; i < numStamps; i++) { … … 662 680 stamps->y->data[i] = ySorted; 663 681 stamps->flux->data[i] = fluxSorted; 664 } 665 682 nTotal += num; 683 } 684 // fprintf (stderr, "nTotal %d\n", nTotal); 685 666 686 return stamps; 667 687 } … … 809 829 float R2 = Sr2 / Sf2; 810 830 811 stamps->normWindow1 = 2. 0*R1;812 stamps->normWindow2 = 2. 0*R2;831 stamps->normWindow1 = 2.75*R1; 832 stamps->normWindow2 = 2.75*R2; 813 833 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2); 814 834 815 835 // Generate a weighting window based on the kron radii 816 836 { 817 float radius = 1.5* PS_MAX(R1, R2);837 float radius = 2.0 * PS_MAX(R1, R2); 818 838 819 839 psImageInit(stamps->window->image, 0.0); … … 826 846 } 827 847 } 848 849 // complain if normWindow1 or normWindow2 are larger than size 850 psAssert(stamps->normWindow1 < size, "norm Window 1 too large"); 851 psAssert(stamps->normWindow2 < size, "norm Window 2 too large"); 828 852 829 853 # else … … 1142 1166 continue; 1143 1167 } 1168 1169 // XXX TEST 1170 if (source->errMag > 0.1) continue; 1171 1144 1172 if (source->modelPSF) { 1145 1173 x->data.F32[numOut] = source->modelPSF->params->data.F32[PM_PAR_XPOS]; -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionVisual.c
r30266 r30289 20 20 #include "pmSubtractionEquation.h" 21 21 #include "pmSubtractionKernels.h" 22 #include "pmSubtractionVisual.h" 22 23 23 24 #include "pmVisual.h" … … 423 424 } 424 425 425 // XXX clear the overlay(s) (red at least!) 426 // clear the overlay (red at least!) 427 KiiEraseOverlay (kapa2, "red"); 426 428 427 429 // get the kernel sizes … … 456 458 int nKernels = 0; 457 459 460 // paste in the kernel images, scaled by sum2 458 461 if (maxStamp->convolutions1) { 459 462 // output image is a grid of NXsub by NYsub sub-images … … 478 481 int yPix = ySub * (2*footprint + 1 + 3) + footprint; 479 482 480 double sum = 0.0;481 483 double sum2 = 0.0; 482 484 for (int y = -footprint; y <= footprint; y++) { 483 485 for (int x = -footprint; x <= footprint; x++) { 484 output->data.F32[y + yPix][x + xPix] = kernel->kernel[y][x];485 sum += kernel->kernel[y][x];486 486 sum2 += PS_SQR(kernel->kernel[y][x]); 487 487 } 488 488 } 489 // fprintf (stderr, "kernel %d, sum %f, sum2: %e\n", i, sum, sum2); 489 float scale = sqrt(sum2) / PS_SQR(2*footprint + 1); 490 for (int y = -footprint; y <= footprint; y++) { 491 for (int x = -footprint; x <= footprint; x++) { 492 output->data.F32[y + yPix][x + xPix] = kernel->kernel[y][x] / scale; 493 } 494 } 490 495 } 491 496 pmVisualScaleImage(kapa2, output, "Image", 0, true); … … 520 525 int yPix = ySub * (2*footprint + 1 + 3) + footprint; 521 526 522 double sum = 0.0;523 527 double sum2 = 0.0; 524 528 for (int y = -footprint; y <= footprint; y++) { 525 529 for (int x = -footprint; x <= footprint; x++) { 526 output->data.F32[y + yPix][x + xPix] = kernel->kernel[y][x];527 sum += kernel->kernel[y][x];528 530 sum2 += PS_SQR(kernel->kernel[y][x]); 529 531 } 530 532 } 531 // fprintf (stderr, "kernel %d, sum %f, sum2: %e\n", i, sum, sum2); 533 float scale = sqrt(sum2) / PS_SQR(2*footprint + 1); 534 for (int y = -footprint; y <= footprint; y++) { 535 for (int x = -footprint; x <= footprint; x++) { 536 output->data.F32[y + yPix][x + xPix] = kernel->kernel[y][x] / scale; 537 } 538 } 532 539 } 533 540 pmVisualScaleImage(kapa2, output, "Image", 1, true); … … 587 594 KiiLoadOverlay (kapa2, overlay, Noverlay, "red"); 588 595 FREE (overlay); 589 return true;590 }591 592 static int footprint = 0;593 static int NX = 0;594 static int NY = 0;595 static psImage *sourceImage = NULL;596 static psImage *targetImage = NULL;597 static psImage *residualImage = NULL;598 static psImage *fresidualImage = NULL;599 static psImage *differenceImage = NULL;600 static psImage *convolutionImage = NULL;601 602 bool pmSubtractionVisualShowFitInit(pmSubtractionStampList *stamps) {603 604 if (!pmVisualTestLevel("ppsub.fit", 1)) return true;605 606 // generate 4 storage images large enough to hold the N stamps:607 608 footprint = stamps->footprint;609 610 float NXf = sqrt(stamps->num);611 NX = (int) NXf == NXf ? NXf : NXf + 1.0;612 613 float NYf = stamps->num / NX;614 NY = (int) NYf == NY ? NYf : NYf + 1.0;615 616 int NXpix = (2*footprint + 1) * NX;617 NXpix += (NX > 1) ? 3 * NX : 0;618 619 int NYpix = (2*footprint + 1) * NY;620 NYpix += (NY > 1) ? 3 * NY : 0;621 622 sourceImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);623 targetImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);624 residualImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);625 fresidualImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);626 differenceImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);627 convolutionImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32);628 629 psImageInit (sourceImage, 0.0);630 psImageInit (targetImage, 0.0);631 psImageInit (residualImage, 0.0);632 psImageInit (fresidualImage, 0.0);633 psImageInit (differenceImage, 0.0);634 psImageInit (convolutionImage, 0.0);635 636 return true;637 }638 639 bool pmSubtractionVisualShowFitAddStamp(psKernel *target, psKernel *source, psKernel *convolution, double background, double norm, int index) {640 641 if (!pmVisualTestLevel("ppsub.stamp", 1)) return true;642 643 double sum;644 645 int NXoff = index % NX;646 int NYoff = index / NX;647 648 int NXpix = NXoff * (2*footprint + 1 + 3) + footprint;649 int NYpix = NYoff * (2*footprint + 1 + 3) + footprint;650 651 // insert the (target) kernel into the (target) image:652 sum = 0.0;653 for (int y = -footprint; y <= footprint; y++) {654 for (int x = -footprint; x <= footprint; x++) {655 targetImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x];656 sum += targetImage->data.F32[y + NYpix][x + NXpix];657 }658 }659 targetImage->data.F32[footprint + 1 + NYpix][NXpix] = sum;660 661 // insert the (source) kernel into the (source) image:662 sum = 0.0;663 for (int y = -footprint; y <= footprint; y++) {664 for (int x = -footprint; x <= footprint; x++) {665 sourceImage->data.F32[y + NYpix][x + NXpix] = source->kernel[y][x];666 sum += sourceImage->data.F32[y + NYpix][x + NXpix];667 }668 }669 sourceImage->data.F32[footprint + 1 + NYpix][NXpix] = sum;670 671 // insert the (convolution) kernel into the (convolution) image:672 sum = 0.0;673 for (int y = -footprint; y <= footprint; y++) {674 for (int x = -footprint; x <= footprint; x++) {675 convolutionImage->data.F32[y + NYpix][x + NXpix] = convolution->kernel[y][x];676 sum += convolutionImage->data.F32[y + NYpix][x + NXpix];677 }678 }679 convolutionImage->data.F32[footprint + 1 + NYpix][NXpix] = sum;680 681 // insert the (difference) kernel into the (difference) image:682 sum = 0.0;683 for (int y = -footprint; y <= footprint; y++) {684 for (int x = -footprint; x <= footprint; x++) {685 differenceImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x] - background - source->kernel[y][x] * norm;686 sum += differenceImage->data.F32[y + NYpix][x + NXpix];687 }688 }689 differenceImage->data.F32[footprint + 1 + NYpix][NXpix] = sum;690 691 // insert the (residual) kernel into the (residual) image:692 sum = 0.0;693 for (int y = -footprint; y <= footprint; y++) {694 for (int x = -footprint; x <= footprint; x++) {695 residualImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x] - background - source->kernel[y][x] * norm - convolution->kernel[y][x];696 sum += residualImage->data.F32[y + NYpix][x + NXpix];697 }698 }699 residualImage->data.F32[footprint + 1 + NYpix][NXpix] = sum;700 701 // insert the (fresidual) kernel into the (fresidual) image:702 for (int y = -footprint; y <= footprint; y++) {703 for (int x = -footprint; x <= footprint; x++) {704 fresidualImage->data.F32[y + NYpix][x + NXpix] = residualImage->data.F32[y + NYpix][x + NXpix] / sqrt(PS_MAX(target->kernel[y][x], 100.0));705 }706 }707 596 return true; 708 597 } … … 730 619 } 731 620 732 bool pmSubtractionVisualShowFit(double norm) { 733 734 // for testing, dump the residual image and exit 735 if (0) { 736 psMetadata *header = psMetadataAlloc();737 psMetadataAddF32 (header, PS_LIST_TAIL, "NORM", 0, "Normalization", norm);738 psFits *fits = psFitsOpen("resid.fits", "w");739 psFitsWriteImage(fits, header, residualImage, 0, NULL);740 psFitsClose(fits);741 // exit (0); 742 } 621 static int footprint = 0; 622 static int NX = 0; 623 static int NY = 0; 624 static psImage *sourceImage = NULL; 625 static psImage *targetImage = NULL; 626 static psImage *residualImage = NULL; 627 static psImage *fresidualImage = NULL; 628 static psImage *differenceImage = NULL; 629 static psImage *convolutionImage = NULL; 630 631 bool pmSubtractionVisualShowFit(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels) { 743 632 744 633 if (!pmVisualTestLevel("ppsub.fit", 1)) return true; … … 746 635 if (!pmVisualInitWindow(&kapa1, "ppSub:Images")) return false; 747 636 if (!pmVisualInitWindow(&kapa2, "ppSub:Misc")) return false; 637 638 // set up holding images for the visualization 639 pmSubtractionVisualShowFitInit (stamps); 640 641 int numKernels = kernels->num; // Number of kernels 642 643 psImage *polyValues = NULL; // Polynomial values 644 psKernel *residual = psKernelAlloc(-stamps->footprint, stamps->footprint, -stamps->footprint, stamps->footprint); // Residual image 645 646 double norm = p_pmSubtractionSolutionNorm(kernels); // Normalisation 647 648 for (int i = 0; i < stamps->num; i++) { 649 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // The stamp of interest 650 if (stamp->status != PM_SUBTRACTION_STAMP_USED) { continue; } 651 652 // Calculate coefficients of the kernel basis functions 653 polyValues = p_pmSubtractionPolynomial(polyValues, kernels->spatialOrder, stamp->xNorm, stamp->yNorm); 654 double background = p_pmSubtractionSolutionBackground(kernels, polyValues); // Difference in background 655 656 psImageInit(residual->image, 0.0); 657 658 if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) { 659 psKernel *target; // Target postage stamp 660 psKernel *source; // Source postage stamp 661 psArray *convolutions; // Convolution postage stamps for each kernel basis function 662 switch (kernels->mode) { 663 case PM_SUBTRACTION_MODE_1: 664 target = stamp->image2; 665 source = stamp->image1; 666 convolutions = stamp->convolutions1; 667 break; 668 case PM_SUBTRACTION_MODE_2: 669 target = stamp->image1; 670 source = stamp->image2; 671 convolutions = stamp->convolutions2; 672 break; 673 default: 674 psAbort("Unsupported subtraction mode: %x", kernels->mode); 675 } 676 677 for (int j = 0; j < numKernels; j++) { 678 psKernel *convolution = convolutions->data[j]; // Convolution 679 double coefficient = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, false); // Coefficient 680 for (int y = - footprint; y <= footprint; y++) { 681 for (int x = - footprint; x <= footprint; x++) { 682 residual->kernel[y][x] += convolution->kernel[y][x] * coefficient; 683 } 684 } 685 } 686 // visualize the target, source, convolution and residual 687 pmSubtractionVisualShowFitAddStamp (target, source, residual, background, norm, i); 688 } else { 689 // Dual convolution 690 psArray *convolutions1 = stamp->convolutions1; // Convolutions of the first image 691 psArray *convolutions2 = stamp->convolutions2; // Convolutions of the second image 692 psKernel *image1 = stamp->image1; // The first image 693 psKernel *image2 = stamp->image2; // The second image 694 695 for (int j = 0; j < numKernels; j++) { 696 psKernel *conv1 = convolutions1->data[j]; // Convolution of first image 697 psKernel *conv2 = convolutions2->data[j]; // Convolution of second image 698 double coeff1 = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, false); // Coefficient 1 699 double coeff2 = p_pmSubtractionSolutionCoeff(kernels, polyValues, j, true); // Coefficient 2 700 701 for (int y = - footprint; y <= footprint; y++) { 702 for (int x = - footprint; x <= footprint; x++) { 703 residual->kernel[y][x] += conv2->kernel[y][x] * coeff2 + conv1->kernel[y][x] * coeff1; 704 } 705 } 706 } 707 // visualize the target, source, convolution and residual 708 pmSubtractionVisualShowFitAddStamp (image2, image1, residual, background, norm, i); 709 } 710 } 711 pmSubtractionVisualShowFitImage(norm); 712 713 return true; 714 } 715 716 // generate 4 storage images large enough to hold the stamps: 717 bool pmSubtractionVisualShowFitInit(pmSubtractionStampList *stamps) { 718 719 footprint = stamps->footprint; 720 721 float NXf = sqrt(stamps->num); 722 NX = (int) NXf == NXf ? NXf : NXf + 1.0; 723 724 float NYf = stamps->num / NX; 725 NY = (int) NYf == NY ? NYf : NYf + 1.0; 726 727 int NXpix = (2*footprint + 1) * NX; 728 NXpix += (NX > 1) ? 3 * NX : 0; 729 730 int NYpix = (2*footprint + 1) * NY; 731 NYpix += (NY > 1) ? 3 * NY : 0; 732 733 sourceImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 734 targetImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 735 residualImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 736 fresidualImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 737 differenceImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 738 convolutionImage = psImageAlloc (NXpix, NYpix, PS_TYPE_F32); 739 740 psImageInit (sourceImage, 0.0); 741 psImageInit (targetImage, 0.0); 742 psImageInit (residualImage, 0.0); 743 psImageInit (fresidualImage, 0.0); 744 psImageInit (differenceImage, 0.0); 745 psImageInit (convolutionImage, 0.0); 746 747 return true; 748 } 749 750 bool pmSubtractionVisualShowFitAddStamp(psKernel *target, psKernel *source, psKernel *convolution, double background, double norm, int index) { 751 752 double sum; 753 754 int NXoff = index % NX; 755 int NYoff = index / NX; 756 757 int NXpix = NXoff * (2*footprint + 1 + 3) + footprint; 758 int NYpix = NYoff * (2*footprint + 1 + 3) + footprint; 759 760 // insert the (target) kernel into the (target) image: 761 sum = 0.0; 762 for (int y = -footprint; y <= footprint; y++) { 763 for (int x = -footprint; x <= footprint; x++) { 764 targetImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x]; 765 sum += targetImage->data.F32[y + NYpix][x + NXpix]; 766 } 767 } 768 targetImage->data.F32[footprint + 1 + NYpix][NXpix] = sum; 769 770 // insert the (source) kernel into the (source) image: 771 sum = 0.0; 772 for (int y = -footprint; y <= footprint; y++) { 773 for (int x = -footprint; x <= footprint; x++) { 774 sourceImage->data.F32[y + NYpix][x + NXpix] = source->kernel[y][x]; 775 sum += sourceImage->data.F32[y + NYpix][x + NXpix]; 776 } 777 } 778 sourceImage->data.F32[footprint + 1 + NYpix][NXpix] = sum; 779 780 // insert the (convolution) kernel into the (convolution) image: 781 sum = 0.0; 782 for (int y = -footprint; y <= footprint; y++) { 783 for (int x = -footprint; x <= footprint; x++) { 784 convolutionImage->data.F32[y + NYpix][x + NXpix] = convolution->kernel[y][x]; 785 sum += convolutionImage->data.F32[y + NYpix][x + NXpix]; 786 } 787 } 788 convolutionImage->data.F32[footprint + 1 + NYpix][NXpix] = sum; 789 790 // insert the (difference) kernel into the (difference) image: 791 sum = 0.0; 792 for (int y = -footprint; y <= footprint; y++) { 793 for (int x = -footprint; x <= footprint; x++) { 794 differenceImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x] - background - source->kernel[y][x] * norm; 795 sum += differenceImage->data.F32[y + NYpix][x + NXpix]; 796 } 797 } 798 differenceImage->data.F32[footprint + 1 + NYpix][NXpix] = sum; 799 800 // insert the (residual) kernel into the (residual) image: 801 sum = 0.0; 802 for (int y = -footprint; y <= footprint; y++) { 803 for (int x = -footprint; x <= footprint; x++) { 804 residualImage->data.F32[y + NYpix][x + NXpix] = target->kernel[y][x] - background - source->kernel[y][x] * norm - convolution->kernel[y][x]; 805 sum += residualImage->data.F32[y + NYpix][x + NXpix]; 806 } 807 } 808 residualImage->data.F32[footprint + 1 + NYpix][NXpix] = sum; 809 810 // insert the (fresidual) kernel into the (fresidual) image: 811 for (int y = -footprint; y <= footprint; y++) { 812 for (int x = -footprint; x <= footprint; x++) { 813 fresidualImage->data.F32[y + NYpix][x + NXpix] = residualImage->data.F32[y + NYpix][x + NXpix] / sqrt(PS_MAX(target->kernel[y][x], 100.0)); 814 } 815 } 816 return true; 817 } 818 819 bool pmSubtractionVisualShowFitImage(double norm) { 748 820 749 821 KiiEraseOverlay (kapa1, "red"); … … 792 864 psVector *x = psVectorAllocEmpty (kernels->num, PS_TYPE_F32); 793 865 psVector *y = psVectorAllocEmpty (kernels->num, PS_TYPE_F32); 866 psVector *dy = psVectorAllocEmpty (kernels->num, PS_TYPE_F32); 794 867 795 868 graphdata.xmin = -1.0; … … 804 877 x->data.F32[i] = i; 805 878 y->data.F32[i] = p_pmSubtractionSolutionCoeff(kernels, polyValues, i, false); 879 dy->data.F32[i] = kernels->solution1err->data.F64[i]; 806 880 graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[i]); 807 881 graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[i]); 808 882 } 809 x->n = y->n = kernels->num;883 x->n = y->n = dy->n = kernels->num; 810 884 811 885 float range; … … 828 902 graphdata.size = 0.5; 829 903 graphdata.style = 2; 904 graphdata.etype |= 0x01; 830 905 831 906 KapaPrepPlot (kapa3, x->n, &graphdata); 832 907 KapaPlotVector (kapa3, x->n, x->data.F32, "x"); 833 908 KapaPlotVector (kapa3, x->n, y->data.F32, "y"); 909 KapaPlotVector (kapa3, x->n, dy->data.F32, "dym"); 910 KapaPlotVector (kapa3, x->n, dy->data.F32, "dyp"); 834 911 835 912 psFree (x); 836 913 psFree (y); 914 psFree (dy); 837 915 psFree (polyValues); 838 916 -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionVisual.h
r30266 r30289 8 8 bool pmSubtractionVisualPlotLeastSquaresResid (const pmSubtractionStampList *stamps, psImage *matrixIn, int nUsed); 9 9 bool pmSubtractionVisualShowSubtraction(psImage *image, psImage *ref, psImage *sub); 10 11 bool pmSubtractionVisualShowFit(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels); 10 12 bool pmSubtractionVisualShowFitInit(pmSubtractionStampList *stamps); 11 13 bool pmSubtractionVisualShowFitAddStamp(psKernel *target, psKernel *source, psKernel *convolution, double background, double norm, int index); 12 bool pmSubtractionVisualShowFit(double norm); 14 bool pmSubtractionVisualShowFitImage(double norm); 15 13 16 bool pmSubtractionVisualPlotFit(const pmSubtractionKernels *kernels); 14 17 bool pmSubtractionVisualShowKernels(pmSubtractionKernels *kernels);
Note:
See TracChangeset
for help on using the changeset viewer.
