Changeset 29004 for trunk/psModules/src/imcombine
- Timestamp:
- Aug 20, 2010, 1:14:11 PM (16 years ago)
- Location:
- trunk/psModules
- Files:
-
- 13 edited
-
. (modified) (1 prop)
-
src/imcombine/pmPSFEnvelope.c (modified) (2 diffs)
-
src/imcombine/pmSubtraction.c (modified) (5 diffs)
-
src/imcombine/pmSubtraction.h (modified) (2 diffs)
-
src/imcombine/pmSubtractionEquation.c (modified) (18 diffs)
-
src/imcombine/pmSubtractionEquation.h (modified) (2 diffs)
-
src/imcombine/pmSubtractionKernels.c (modified) (19 diffs)
-
src/imcombine/pmSubtractionKernels.h (modified) (2 diffs)
-
src/imcombine/pmSubtractionMatch.c (modified) (1 diff)
-
src/imcombine/pmSubtractionMatch.h (modified) (1 diff)
-
src/imcombine/pmSubtractionStamps.c (modified) (10 diffs)
-
src/imcombine/pmSubtractionStamps.h (modified) (2 diffs)
-
src/imcombine/pmSubtractionVisual.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
- Property svn:mergeinfo deleted
-
trunk/psModules/src/imcombine/pmPSFEnvelope.c
r28332 r29004 10 10 #include "pmHDU.h" 11 11 #include "pmFPA.h" 12 #include "pmReadoutFake.h" 13 14 #include "pmMoments.h" 12 13 #include "pmTrend2D.h" 15 14 #include "pmResiduals.h" 16 15 #include "pmGrowthCurve.h" 17 #include "pmTrend2D.h"18 #include "pmPSF.h"19 #include "pmModel.h"20 #include "pmModelClass.h"21 #include "pmModelUtils.h"22 16 #include "pmSpan.h" 17 #include "pmFootprintSpans.h" 23 18 #include "pmFootprint.h" 24 19 #include "pmPeaks.h" 20 #include "pmMoments.h" 21 #include "pmModelFuncs.h" 22 #include "pmModel.h" 23 #include "pmModelUtils.h" 24 #include "pmModelClass.h" 25 #include "pmSourceMasks.h" 26 #include "pmSourceExtendedPars.h" 27 #include "pmSourceDiffStats.h" 25 28 #include "pmSource.h" 26 #include "pmSourceUtils.h"27 29 #include "pmSourceFitModel.h" 30 #include "pmPSF.h" 28 31 #include "pmPSFtry.h" 29 32 30 33 #include "pmReadoutFake.h" 31 34 #include "pmPSFEnvelope.h" 32 35 #include "pmStackVisual.h" … … 410 413 options->chiFluxTrend = false; // All sources have similar flux, so fitting a trend often fails 411 414 412 pmSourceFitModelInit(SOURCE_FIT_ITERATIONS, 0.01, VARIANCE_VAL, true); 415 // options which modify the behavior of the model fitting 416 options->fitOptions = pmSourceFitOptionsAlloc(); 417 options->fitOptions->nIter = SOURCE_FIT_ITERATIONS; 418 options->fitOptions->minTol = 0.01; 419 options->fitOptions->maxTol = 1.00; 420 options->fitOptions->poissonErrors = true; 421 options->fitOptions->weight = VARIANCE_VAL; 422 options->fitOptions->mode = PM_SOURCE_FIT_PSF; 423 413 424 pmModelClassSetLimits(PM_MODEL_LIMITS_STRICT); // Important for getting a good stack target PSF 414 425 -
trunk/psModules/src/imcombine/pmSubtraction.c
r28667 r29004 33 33 #define USE_KERNEL_ERR // Use kernel error image? 34 34 #define NUM_COVAR_POS 5 // Number of positions for covariance calculation 35 36 // XXX we need to pass these fwhm values elsewhere. These should go on one of the structure, but 37 // things are too confusing to do that now. just save them here. 38 static float FWHM1 = NAN; 39 static float FWHM2 = NAN; 35 40 36 41 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 752 757 753 758 754 bool pmSubtractionConvolveStamp (pmSubtractionStamp *stamp, constpmSubtractionKernels *kernels, int footprint)759 bool pmSubtractionConvolveStamp (pmSubtractionStamp *stamp, pmSubtractionKernels *kernels, int footprint) 755 760 { 756 761 PS_ASSERT_PTR_NON_NULL(stamp, false); … … 774 779 stamp->convolutions1 = convolveStamp(stamp->convolutions1, stamp->image1, kernels, footprint); 775 780 stamp->convolutions2 = convolveStamp(stamp->convolutions2, stamp->image2, kernels, footprint); 781 if (!pmSubtractionKernelPenaltiesStamp(stamp, kernels)) { 782 psAbort("failure in penalties"); 783 } 776 784 break; 777 785 default: … … 1215 1223 bool threaded = pmSubtractionThreaded(); // Running threaded? 1216 1224 1225 // XXX This is no longer used 1217 1226 psImage *convMask = NULL; // Convolved mask image (common to inputs 1 and 2) 1218 1227 if (subMask) { … … 1413 1422 return true; 1414 1423 } 1424 1425 bool pmSubtractionGetFWHMs(float *fwhm1, float *fwhm2) { 1426 1427 *fwhm1 = FWHM1; 1428 *fwhm2 = FWHM2; 1429 return true; 1430 } 1431 1432 bool pmSubtractionSetFWHMs(float fwhm1, float fwhm2) { 1433 1434 FWHM1 = fwhm1; 1435 FWHM2 = fwhm2; 1436 return true; 1437 } -
trunk/psModules/src/imcombine/pmSubtraction.h
r26893 r29004 59 59 /// Convolve the reference stamp with the kernel components 60 60 bool pmSubtractionConvolveStamp(pmSubtractionStamp *stamp, ///< Stamp to convolve 61 constpmSubtractionKernels *kernels, ///< Kernel parameters61 pmSubtractionKernels *kernels, ///< Kernel parameters 62 62 int footprint ///< Half-size of region over which to calculate equation 63 63 ); … … 157 157 ); 158 158 159 bool pmSubtractionGetFWHMs(float *fwhm1, float *fwhm2); 160 bool pmSubtractionSetFWHMs(float fwhm1, float fwhm2); 161 159 162 /// @} 160 163 #endif -
trunk/psModules/src/imcombine/pmSubtractionEquation.c
r28405 r29004 38 38 const psImage *polyValues, // Spatial polynomial values 39 39 int footprint, // (Half-)Size of stamp 40 int normWindow, // Window (half-)size for normalisation measurement 40 int normWindow1, // Window (half-)size for normalisation measurement 41 int normWindow2, // Window (half-)size for normalisation measurement 41 42 const pmSubtractionEquationCalculationMode mode 42 43 ) … … 184 185 double one = 1.0; 185 186 186 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow )) {187 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow1)) { 187 188 normI1 += ref; 189 } 190 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow2)) { 188 191 normI2 += in; 189 192 } … … 214 217 215 218 *norm = normI2 / normI1; 219 220 fprintf (stderr, "normValue: %f %f %f\n", normI1, normI2, *norm); 216 221 217 222 if (mode & PM_SUBTRACTION_EQUATION_NORM) { … … 262 267 const psImage *polyValues, // Spatial polynomial values 263 268 int footprint, // (Half-)Size of stamp 264 int normWindow, // Window (half-)size for normalisation measurement 269 int normWindow1, // Window (half-)size for normalisation measurement 270 int normWindow2, // Window (half-)size for normalisation measurement 265 271 const pmSubtractionEquationCalculationMode mode 266 272 ) … … 492 498 double i1i2 = i1 * i2; 493 499 494 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow )) {500 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow1)) { 495 501 normI1 += i1; 502 } 503 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(normWindow2)) { 496 504 normI2 += i2; 497 505 } … … 522 530 523 531 *norm = normI2 / normI1; 532 fprintf (stderr, "normValue: %f %f %f\n", normI1, normI2, *norm); 524 533 525 534 if (mode & PM_SUBTRACTION_EQUATION_NORM) { … … 559 568 // Add in penalty term to least-squares vector 560 569 bool calculatePenalty(psImage *matrix, // Matrix to which to add in penalty term 561 psVector *vector, // Vector to which to add in penalty term562 const pmSubtractionKernels *kernels, // Kernel parameters563 float norm // Normalisation564 )570 psVector *vector, // Vector to which to add in penalty term 571 const pmSubtractionKernels *kernels, // Kernel parameters 572 float norm // Normalisation 573 ) 565 574 { 566 575 if (kernels->penalty == 0.0) { … … 568 577 } 569 578 570 psVector *penalties = kernels->penalties; // Penalties for each kernel component 579 psVector *penalties1 = kernels->penalties1; // Penalties for each kernel component (input) 580 psVector *penalties2 = kernels->penalties2; // Penalties for each kernel component (ref) 581 571 582 int spatialOrder = kernels->spatialOrder; // Order of spatial variations 572 583 int numKernels = kernels->num; // Number of kernel components … … 588 599 for (int xOrder = 0; xOrder <= spatialOrder - yOrder; xOrder++, index += numKernels) { 589 600 // Contribution to chi^2: a_i^2 P_i 590 psAssert(isfinite(penalties->data.F32[i]), "Invalid penalty"); 591 matrix->data.F64[index][index] += norm * penalties->data.F32[i]; 601 psAssert(isfinite(penalties1->data.F32[i]), "Invalid penalty"); 602 fprintf (stderr, "penalty: %f + %f (%f * %f)\n", matrix->data.F64[index][index], norm * penalties1->data.F32[i], norm, penalties1->data.F32[i]); 603 matrix->data.F64[index][index] += norm * penalties1->data.F32[i]; 592 604 if (kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 593 matrix->data.F64[index + numParams + 2][index + numParams + 2] += norm * penalties->data.F32[i]; 605 fprintf (stderr, "penalty: (x^%d y^%d fwhm %f) : %f + %f (%f * %f)\n", kernels->u->data.S32[index], kernels->v->data.S32[index], kernels->widths->data.F32[index], 606 matrix->data.F64[index + numParams + 2][index + numParams + 2], norm * penalties2->data.F32[i], norm, penalties2->data.F32[i]); 607 matrix->data.F64[index + numParams + 2][index + numParams + 2] += norm * penalties2->data.F32[i]; 594 608 // matrix[i][i] is ~ (k_i * I_1)(k_i * I_1) 595 609 // penalties scale with second moments … … 682 696 683 697 pmSubtractionStampList *stamps = job->args->data[0]; // List of stamps 684 constpmSubtractionKernels *kernels = job->args->data[1]; // Kernels698 pmSubtractionKernels *kernels = job->args->data[1]; // Kernels 685 699 int index = PS_SCALAR_VALUE(job->args->data[2], S32); // Stamp index 686 700 pmSubtractionEquationCalculationMode mode = PS_SCALAR_VALUE(job->args->data[3], S32); // calculation model … … 689 703 } 690 704 691 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, constpmSubtractionKernels *kernels,705 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels, 692 706 int index, const pmSubtractionEquationCalculationMode mode) 693 707 { … … 778 792 status = calculateMatrixVector(stamp->matrix, stamp->vector, &stamp->norm, stamp->image2, stamp->image1, 779 793 weight, window, stamp->convolutions1, kernels, 780 polyValues, footprint, stamps->normWindow , mode);794 polyValues, footprint, stamps->normWindow1, stamps->normWindow2, mode); 781 795 break; 782 796 case PM_SUBTRACTION_MODE_2: 783 797 status = calculateMatrixVector(stamp->matrix, stamp->vector, &stamp->norm, stamp->image1, stamp->image2, 784 798 weight, window, stamp->convolutions2, kernels, 785 polyValues, footprint, stamps->normWindow , mode);799 polyValues, footprint, stamps->normWindow2, stamps->normWindow1, mode); 786 800 break; 787 801 case PM_SUBTRACTION_MODE_DUAL: … … 789 803 stamp->image1, stamp->image2, 790 804 weight, window, stamp->convolutions1, stamp->convolutions2, 791 kernels, polyValues, footprint, stamps->normWindow , mode);805 kernels, polyValues, footprint, stamps->normWindow1, stamps->normWindow2, mode); 792 806 break; 793 807 default: … … 830 844 } 831 845 832 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, constpmSubtractionKernels *kernels,846 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, pmSubtractionKernels *kernels, 833 847 const pmSubtractionEquationCalculationMode mode) 834 848 { … … 996 1010 } 997 1011 1012 // double normValue = 1.0; 998 1013 double normValue = stats->robustMedian; 999 1014 // double bgValue = 0.0; … … 1023 1038 } 1024 1039 # endif 1040 1041 #if (1) 1042 for (int i = 0; i < solution->n; i++) { 1043 fprintf(stderr, "Single solution %d: %lf\n", i, solution->data.F64[i]); 1044 } 1045 #endif 1025 1046 1026 1047 if (!kernels->solution1) { … … 1096 1117 1097 1118 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation 1098 calculatePenalty(sumMatrix, sumVector, kernels, sumMatrix->data.F64[normIndex][normIndex] / 100 0.0);1119 calculatePenalty(sumMatrix, sumVector, kernels, sumMatrix->data.F64[normIndex][normIndex] / 100.0); 1099 1120 #endif 1100 1121 … … 1177 1198 1178 1199 1179 #if def TESTING1200 #if (1) 1180 1201 for (int i = 0; i < solution->n; i++) { 1181 1202 fprintf(stderr, "Dual solution %d: %lf\n", i, solution->data.F64[i]); -
trunk/psModules/src/imcombine/pmSubtractionEquation.h
r26893 r29004 19 19 /// Calculate the least-squares equation to match the image quality for a single stamp 20 20 bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, ///< Stamps 21 constpmSubtractionKernels *kernels, ///< Kernel parameters21 pmSubtractionKernels *kernels, ///< Kernel parameters 22 22 int index, ///< Index of stamp 23 23 const pmSubtractionEquationCalculationMode mode … … 26 26 /// Calculate the least-squares equation to match the image quality 27 27 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, ///< Stamps 28 constpmSubtractionKernels *kernels, ///< Kernel parameters28 pmSubtractionKernels *kernels, ///< Kernel parameters 29 29 const pmSubtractionEquationCalculationMode mode 30 30 ); -
trunk/psModules/src/imcombine/pmSubtractionKernels.c
r27335 r29004 26 26 psFree(kernels->vStop); 27 27 psFree(kernels->preCalc); 28 psFree(kernels->penalties); 28 psFree(kernels->penalties1); 29 psFree(kernels->penalties2); 29 30 psFree(kernels->solution1); 30 31 psFree(kernels->solution2); … … 140 141 kernels->v = psVectorRealloc(kernels->v, start + numNew); 141 142 kernels->preCalc = psArrayRealloc(kernels->preCalc, start + numNew); 142 kernels->penalties = psVectorRealloc(kernels->penalties, start + numNew); 143 144 kernels->penalties1 = psVectorRealloc(kernels->penalties1, start + numNew); 145 kernels->penalties2 = psVectorRealloc(kernels->penalties2, start + numNew); 146 143 147 kernels->inner = start; 144 148 kernels->num += numNew; … … 156 160 kernels->v->data.S32[index] = v; 157 161 kernels->preCalc->data[index] = NULL; 158 kernels->penalties->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v)); 159 psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty"); 162 163 // XXX this needs to be changed to use the *convolved* second moment 164 kernels->penalties1->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v)); 165 psAssert (isfinite(kernels->penalties1->data.F32[index]), "invalid penalty"); 166 167 kernels->penalties2->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v)); 168 psAssert (isfinite(kernels->penalties2->data.F32[index]), "invalid penalty"); 169 160 170 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v); 161 171 } … … 166 176 kernels->v->n = start + numNew; 167 177 kernels->preCalc->n = start + numNew; 168 kernels->penalties->n = start + numNew; 178 179 kernels->penalties1->n = start + numNew; 180 kernels->penalties2->n = start + numNew; 169 181 170 182 return true; 171 183 } 172 184 173 bool pmSubtractionKernelPreCalcNormalize(pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc,174 int index, int size, int uOrder, int vOrder, float fwhm,175 bool AlardLuptonStyle, bool forceZeroNull)185 static bool pmSubtractionKernelPreCalcNormalize(pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, 186 int index, int uOrder, int vOrder, float fwhm, 187 bool AlardLuptonStyle, bool forceZeroNull) 176 188 { 177 189 // we have 4 cases here: … … 182 194 183 195 // Calculate moments 184 double penalty = 0.0; // Moment, for penalty185 196 double sum = 0.0, sum2 = 0.0; // Sum of kernel component 186 197 float min = INFINITY, max = -INFINITY; // Minimum and maximum kernel value 187 for (int v = -size; v <= size; v++) { 188 for (int u = -size; u <= size; u++) { 198 199 for (int v = preCalc->kernel->yMin; v <= preCalc->kernel->yMax; v++) { 200 for (int u = preCalc->kernel->xMin; u <= preCalc->kernel->xMax; u++) { 189 201 double value = preCalc->kernel->kernel[v][u]; 190 202 double value2 = PS_SQR(value); 191 203 sum += value; 192 204 sum2 += value2; 193 penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v)));194 205 min = PS_MIN(value, min); 195 206 max = PS_MAX(value, max); … … 198 209 199 210 #if 0 200 fprintf(stderr, "%d raw: %lf, null: %f, min: %lf, max: %lf , moment: %lf\n", index, sum, preCalc->kernel->kernel[0][0], min, max, penalty);211 fprintf(stderr, "%d raw: %lf, null: %f, min: %lf, max: %lf\n", index, sum, preCalc->kernel->kernel[0][0], min, max); 201 212 #endif 202 213 … … 207 218 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 208 219 // Even functions: normalise to unit sum and subtract null pixel so that sum is zero 209 scale2D = 1.0 / fabs(sum); 220 // Re-normalize 221 // scale2D = 1.0 / fabs(sum); 222 scale2D = 1.0 / sqrt(sum2); 210 223 zeroNull = true; 211 224 } else { … … 239 252 240 253 psBinaryOp(preCalc->kernel->image, preCalc->kernel->image, "*", psScalarAlloc(scale2D, PS_TYPE_F32)); 241 penalty *= 1.0 / sum2;242 254 243 255 if (zeroNull) { 244 preCalc->kernel->kernel[0][0] -= 1.0; 245 } 246 247 #if 0 256 // preCalc->kernel->kernel[0][0] -= 1.0; 257 preCalc->kernel->kernel[0][0] -= sum / sqrt (sum2); 258 } 259 260 #if 1 248 261 { 249 double sum = 0.0; // Sum of kernel component 262 double Sum = 0.0; // Sum of kernel component 263 double Sum2 = 0.0; // Sum of kernel component 250 264 float min = INFINITY, max = -INFINITY; // Minimum and maximum kernel value 251 for (int v = -size; v <= size; v++) { 252 for (int u = -size; u <= size; u++) { 253 sum += preCalc->kernel->kernel[v][u]; 265 for (int v = preCalc->kernel->yMin; v <= preCalc->kernel->yMax; v++) { 266 for (int u = preCalc->kernel->xMin; u <= preCalc->kernel->xMax; u++) { 267 double value = preCalc->kernel->kernel[v][u]; 268 Sum += value; 269 Sum2 += PS_SQR(value); 254 270 min = PS_MIN(preCalc->kernel->kernel[v][u], min); 255 271 max = PS_MAX(preCalc->kernel->kernel[v][u], max); 256 272 } 257 273 } 258 fprintf(stderr, "%d mod: %lf, null: %f, min: %lf, max: %lf, scale: %f\n", index, sum, preCalc->kernel->kernel[0][0], min, max, scale2D);274 fprintf(stderr, "%d sum: %lf, sum2: %lf, null: %f, min: %lf, max: %lf, scale: %f\n", index, Sum, Sum2, preCalc->kernel->kernel[0][0], min, max, scale2D); 259 275 } 260 276 #endif … … 267 283 } 268 284 kernels->preCalc->data[index] = preCalc; 269 kernels->penalties->data.F32[index] = kernels->penalty * penalty; 270 psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty"); 271 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, penalty); 285 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d\n", index, fwhm, uOrder, vOrder); 272 286 273 287 return true; … … 321 335 322 336 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values 323 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,uOrder, vOrder, fwhms->data.F32[i], true, false);324 // pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,uOrder, vOrder, fwhms->data.F32[i], false, false);337 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, uOrder, vOrder, fwhms->data.F32[i], true, false); 338 // pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, uOrder, vOrder, fwhms->data.F32[i], false, false); 325 339 } 326 340 } … … 379 393 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 380 394 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values 381 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,uOrder, vOrder, fwhms->data.F32[i], true, false);395 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, uOrder, vOrder, fwhms->data.F32[i], true, false); 382 396 } 383 397 } … … 385 399 // XXX modify size for hermitians to account for sqrt(2) in Hermitian definition (relative to ISIS Gaussian) 386 400 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS_RADIAL, order, order, size, sigma / sqrt(2.0)); // structure to hold precalculated values 387 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,order, order, fwhms->data.F32[i], true, true);401 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, order, order, fwhms->data.F32[i], true, true); 388 402 } 389 403 } … … 437 451 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 438 452 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 439 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,uOrder, vOrder, fwhms->data.F32[i], true, false);453 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, uOrder, vOrder, fwhms->data.F32[i], true, false); 440 454 } 441 455 } … … 506 520 507 521 // XXX do we use Alard-Lupton normalization (last param true) or not? 508 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size,uOrder, vOrder, fwhms->data.F32[i], true, false);522 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, uOrder, vOrder, fwhms->data.F32[i], true, false); 509 523 510 524 // XXXX test demo that deconvolved kernel is valid … … 572 586 kernels->preCalc = psArrayAlloc(numBasisFunctions); 573 587 kernels->penalty = penalty; 574 kernels->penalties = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 588 kernels->penalties1 = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 589 psVectorInit(kernels->penalties1, NAN); 590 kernels->penalties2 = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 591 psVectorInit(kernels->penalties2, NAN); 592 kernels->havePenalties = false; 575 593 kernels->size = size; 576 594 kernels->inner = 0; … … 771 789 772 790 psWarning("Kernel penalty for dual-convolution is not configured for SPAM kernels."); 773 psVectorInit(kernels->penalties, 0.0); 791 psVectorInit(kernels->penalties1, 0.0); 792 psVectorInit(kernels->penalties2, 0.0); 774 793 775 794 return kernels; … … 866 885 867 886 psWarning("Kernel penalty for dual-convolution is not configured for FRIES kernels."); 868 psVectorInit(kernels->penalties, 0.0); 887 psVectorInit(kernels->penalties1, 0.0); 888 psVectorInit(kernels->penalties2, 0.0); 869 889 870 890 return kernels; … … 1040 1060 kernels->u->data.S32[index] = uOrder; 1041 1061 kernels->v->data.S32[index] = vOrder; 1042 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 1043 if (!isfinite(kernels->penalties->data.F32[index])) { 1062 1063 // XXX convert to use the convolved 2nd moment 1064 kernels->penalties1->data.F32[index] = kernels->penalty * fabsf(moment); 1065 if (!isfinite(kernels->penalties1->data.F32[index])) { 1066 psAbort ("invalid penalty"); 1067 } 1068 kernels->penalties2->data.F32[index] = kernels->penalty * fabsf(moment); 1069 if (!isfinite(kernels->penalties2->data.F32[index])) { 1044 1070 psAbort ("invalid penalty"); 1045 1071 } … … 1247 1273 out->preCalc = psMemIncrRefCounter(in->preCalc); 1248 1274 out->penalty = in->penalty; 1249 out->penalties = psMemIncrRefCounter(in->penalties); 1275 out->penalties1 = psMemIncrRefCounter(in->penalties1); 1276 out->penalties2 = psMemIncrRefCounter(in->penalties2); 1250 1277 out->uStop = psMemIncrRefCounter(in->uStop); 1251 1278 out->vStop = psMemIncrRefCounter(in->vStop); -
trunk/psModules/src/imcombine/pmSubtractionKernels.h
r26893 r29004 39 39 psArray *preCalc; ///< Array of images containing pre-calculated kernel (for ISIS, HERM or DECONV_HERM) 40 40 float penalty; ///< Penalty for wideness 41 psVector *penalties; ///< Penalty for each kernel component 41 psVector *penalties1; ///< Penalty for each kernel component 42 psVector *penalties2; ///< Penalty for each kernel component 43 bool havePenalties; ///< flag to test if we have already calculated the penalties or not. 42 44 int size; ///< The half-size of the kernel 43 45 int inner; ///< The size of an inner region … … 308 310 ); 309 311 310 311 312 #endif -
trunk/psModules/src/imcombine/pmSubtractionMatch.c
r28405 r29004 1304 1304 float scale = PS_MAX(fwhm1, fwhm2) / scaleRef; // Scaling factor 1305 1305 1306 // XXX save these values in a static for later use 1307 pmSubtractionSetFWHMs(fwhm1, fwhm2); 1308 1306 1309 if (isfinite(scaleMin) && scale < scaleMin) { 1307 1310 scale = scaleMin; -
trunk/psModules/src/imcombine/pmSubtractionMatch.h
r26893 r29004 110 110 ); 111 111 112 113 112 #endif -
trunk/psModules/src/imcombine/pmSubtractionStamps.c
r27402 r29004 7 7 #include <pslib.h> 8 8 9 #include "pmErrorCodes.h" 10 #include "pmHDU.h" 11 #include "pmFPA.h" 12 9 13 // All these includes required to get stamps out of an array of pmSources 10 #include "pmMoments.h" 14 #include "pmTrend2D.h" 15 #include "pmResiduals.h" 16 #include "pmGrowthCurve.h" 11 17 #include "pmSpan.h" 18 #include "pmFootprintSpans.h" 12 19 #include "pmFootprint.h" 13 20 #include "pmPeaks.h" 14 #include "pmResiduals.h" 15 #include "pmHDU.h" 16 #include "pmFPA.h" 17 #include "pmGrowthCurve.h" 18 #include "pmTrend2D.h" 19 #include "pmPSF.h" 21 #include "pmMoments.h" 22 #include "pmModelFuncs.h" 20 23 #include "pmModel.h" 24 #include "pmSourceMasks.h" 25 #include "pmSourceExtendedPars.h" 26 #include "pmSourceDiffStats.h" 21 27 #include "pmSource.h" 22 #include "pmErrorCodes.h"23 28 24 29 #include "pmSubtraction.h" … … 46 51 psFree(list->y); 47 52 psFree(list->flux); 48 psFree(list->window); 53 psFree(list->window1); 54 psFree(list->window2); 49 55 } 50 56 … … 225 231 list->y = NULL; 226 232 list->flux = NULL; 227 list->window = NULL;228 233 list->normFrac = normFrac; 229 list->normWindow = 0; 234 list->window1 = NULL; 235 list->window2 = NULL; 236 list->normWindow1 = 0; 237 list->normWindow2 = 0; 230 238 list->footprint = footprint; 231 239 list->sysErr = sysErr; … … 248 256 out->y = NULL; 249 257 out->flux = NULL; 250 out->window = psMemIncrRefCounter(in->window); 258 out->window1 = psMemIncrRefCounter(in->window1); 259 out->window2 = psMemIncrRefCounter(in->window2); 251 260 out->footprint = in->footprint; 252 out->normWindow = in->normWindow; 261 out->normWindow1 = in->normWindow1; 262 out->normWindow2 = in->normWindow2; 253 263 254 264 for (int i = 0; i < num; i++) { … … 638 648 int size = stamps->footprint; // Size of postage stamps 639 649 640 psFree (stamps->window); 641 stamps->window = psKernelAlloc(-size, size, -size, size); 642 psImageInit(stamps->window->image, 0.0); 650 psFree (stamps->window1); 651 stamps->window1 = psKernelAlloc(-size, size, -size, size); 652 psImageInit(stamps->window1->image, 0.0); 653 654 psFree (stamps->window2); 655 stamps->window2 = psKernelAlloc(-size, size, -size, size); 656 psImageInit(stamps->window2->image, 0.0); 643 657 644 658 // generate normalizations for each stamp … … 669 683 670 684 // generate the window pixels 671 double sum = 0.0; // Sum inside the window 672 float maxValue = 0.0; // Maximum value, for normalisation 685 double sum1 = 0.0; // Sum inside the window 686 double sum2 = 0.0; // Sum inside the window 687 float maxValue1 = 0.0; // Maximum value, for normalisation 688 float maxValue2 = 0.0; // Maximum value, for normalisation 673 689 for (int y = -size; y <= size; y++) { 674 690 for (int x = -size; x <= size; x++) { … … 691 707 } 692 708 float f1 = stats->robustMedian; 709 693 710 psStatsInit (stats); 694 711 if (!psVectorStats (stats, flux2, NULL, NULL, 0)) { … … 697 714 float f2 = stats->robustMedian; 698 715 699 stamps->window ->kernel[y][x] = f1 + f2;716 stamps->window1->kernel[y][x] = f1; 700 717 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 701 sum += stamps->window->kernel[y][x]; 702 } 703 maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]); 704 } 705 } 706 707 psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n", 708 sum, (1.0 - stamps->normFrac) * sum); 709 bool done = false; 710 for (int radius = 1; radius <= size && !done; radius++) { 711 double within = 0.0; 718 sum1 += stamps->window1->kernel[y][x]; 719 } 720 maxValue1 = PS_MAX(maxValue1, stamps->window1->kernel[y][x]); 721 722 stamps->window2->kernel[y][x] = f2; 723 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 724 sum2 += stamps->window2->kernel[y][x]; 725 } 726 maxValue2 = PS_MAX(maxValue2, stamps->window2->kernel[y][x]); 727 } 728 } 729 730 psTrace("psModules.imcombine", 3, "Window total (1): %f, threshold: %f\n", sum1, (1.0 - stamps->normFrac) * sum1); 731 psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2); 732 733 # if (0) 734 // this block attempts to calculate the radius based on the first radial moment 735 bool done1 = false; 736 bool done2 = false; 737 double prior1 = 0.0; 738 double prior2 = 0.0; 739 for (int y = -size; y <= size; y++) { 740 for (int x = -size; x <= size; x++) { 741 float r = hypot(x, y); 742 Sr1 += r * stamps->window1->kernel[y][x]; 743 Sr2 += r * stamps->window2->kernel[y][x]; 744 Sf1 += stamps->window1->kernel[y][x]; 745 Sf2 += stamps->window2->kernel[y][x]; 746 } 747 } 748 749 float R1 = Sr1 / Sf1; 750 float R2 = Sr2 / Sf2; 751 752 stamps->normWindow1 = 2.5*R1; 753 stamps->normWindow1 = 2.5*R2; 754 # else 755 // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent). 756 // It did not do very well (though a true curve-of-growth analysis might be better...) 757 bool done1 = false; 758 bool done2 = false; 759 double prior1 = 0.0; 760 double prior2 = 0.0; 761 double delta1o = 1.0; 762 double delta2o = 1.0; 763 for (int radius = 1; radius <= size && !(done1 && done2); radius++) { 764 double within1 = 0.0; 765 double within2 = 0.0; 712 766 for (int y = -radius; y <= radius; y++) { 713 767 for (int x = -radius; x <= radius; x++) { 714 768 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 715 within += stamps->window->kernel[y][x];769 within1 += stamps->window1->kernel[y][x]; 716 770 } 717 } 718 } 719 psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within); 720 if (within > (1.0 - stamps->normFrac) * sum) { 721 stamps->normWindow = radius; 722 done = true; 723 } 724 } 725 726 psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow); 727 if (stamps->normWindow == 0 || stamps->normWindow >= size) { 728 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size."); 771 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 772 within2 += stamps->window2->kernel[y][x]; 773 } 774 } 775 } 776 double delta1 = (within1 - prior1) / within1; 777 if (!done1 && (fabs(delta1) < stamps->normFrac)) { 778 // interpolate to the radius at which delta2 is normFrac: 779 stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1); 780 fprintf (stderr, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1); 781 done1 = true; 782 } 783 double delta2 = (within2 - prior2) / within2; 784 if (!done2 && (fabs(delta2) < stamps->normFrac)) { 785 // interpolate to the radius at which delta2 is normFrac: 786 stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2); 787 fprintf (stderr, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2); 788 done2 = true; 789 } 790 psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2); 791 792 prior1 = within1; 793 prior2 = within2; 794 delta1o = delta1; 795 delta2o = delta2; 796 797 // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) { 798 // stamps->normWindow1 = radius; 799 // done1 = true; 800 // } 801 // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) { 802 // stamps->normWindow2 = radius; 803 // done2 = true; 804 // } 805 806 } 807 # endif 808 809 psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2); 810 if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) { 811 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1)."); 812 return false; 813 } 814 if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) { 815 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2)."); 729 816 return false; 730 817 } … … 733 820 for (int y = -size; y <= size; y++) { 734 821 for (int x = -size; x <= size; x++) { 735 stamps->window->kernel[y][x] /= maxValue; 736 } 737 } 738 739 #if 0 822 stamps->window1->kernel[y][x] /= maxValue1; 823 } 824 } 825 // re-normalize so chisquare values are sensible 826 for (int y = -size; y <= size; y++) { 827 for (int x = -size; x <= size; x++) { 828 stamps->window2->kernel[y][x] /= maxValue2; 829 } 830 } 831 832 #if 1 740 833 { 741 psFits *fits = psFitsOpen ("window.fits", "w"); 742 psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL); 834 psFits *fits = NULL; 835 fits = psFitsOpen ("window1.fits", "w"); 836 psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL); 837 psFitsClose (fits); 838 fits = psFitsOpen ("window2.fits", "w"); 839 psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL); 743 840 psFitsClose (fits); 744 841 } … … 747 844 psFree (stats); 748 845 psFree (flux1); 749 psFree (flux2);846 psFree (flux2); 750 847 psFree (norm1); 751 848 psFree (norm2); 752 849 return true; 850 } 851 852 static pthread_mutex_t getPenaltiesMutex = PTHREAD_MUTEX_INITIALIZER; 853 854 // kernels->penalty is an overall scaling factor (user-supplied) 855 bool pmSubtractionKernelPenaltiesStamp(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels) 856 { 857 // we only need the penalties if we are doing dual convolution 858 if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) return true; 859 860 // we only calculate the penalties once. 861 if (kernels->havePenalties) return true; 862 863 // in a threaded context, only one thread can calculate the penalties. attempt to grab a 864 // mutex before continuing 865 pthread_mutex_lock(&getPenaltiesMutex); 866 867 // did someone else already get the mutex and do this? 868 if (kernels->havePenalties) { 869 pthread_mutex_unlock(&getPenaltiesMutex); 870 return true; 871 } 872 873 for (int i = 0; i < kernels->num; i++) { 874 pmSubtractionKernelPenalties(stamp, kernels, i); 875 } 876 877 kernels->havePenalties = true; 878 pthread_mutex_unlock(&getPenaltiesMutex); 879 return true; 880 } 881 882 # define EMPIRICAL 0 883 884 // kernels->penalty is an overall scaling factor (user-supplied) 885 bool pmSubtractionKernelPenalties(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels, int index) 886 { 887 float penalty1, penalty2; 888 float fwhm1, fwhm2; 889 890 // XXX this is annoyingly hack-ish 891 pmSubtractionGetFWHMs(&fwhm1, &fwhm2); 892 893 bool zeroNull = false; 894 int uOrder = kernels->u->data.S32[index]; 895 int vOrder = kernels->v->data.S32[index]; 896 if (uOrder % 2 == 0 && vOrder % 2 == 0) zeroNull = true; 897 898 if (EMPIRICAL) { 899 psKernel *convolution1 = stamp->convolutions1->data[index]; 900 penalty1 = pmSubtractionKernelPenaltySingle(convolution1, zeroNull); 901 902 psKernel *convolution2 = stamp->convolutions2->data[index]; 903 penalty2 = pmSubtractionKernelPenaltySingle(convolution2, zeroNull); 904 } else { 905 pmSubtractionKernelPreCalc *kernel = kernels->preCalc->data[index]; 906 float M2 = pmSubtractionKernelPenaltySingle(kernel->kernel, zeroNull); 907 908 penalty1 = M2 + PS_SQR(fwhm1 / 2.35); // rescale the unconvolved second-moment by the image second moment 909 penalty2 = M2 + PS_SQR(fwhm2 / 2.35); // rescale the unconvolved second-moment by the image second moment 910 } 911 kernels->penalties1->data.F32[index] = kernels->penalty * penalty1; 912 psAssert (isfinite(kernels->penalties1->data.F32[index]), "invalid penalty"); 913 914 kernels->penalties2->data.F32[index] = kernels->penalty * penalty2; 915 psAssert (isfinite(kernels->penalties2->data.F32[index]), "invalid penalty"); 916 917 fprintf(stderr, "penalty1: %f, penalty2: %f\n", penalty1, penalty2); 918 919 return true; 920 } 921 922 float pmSubtractionKernelPenaltySingle(psKernel *kernel, bool zeroNull) 923 { 924 // Calculate moments 925 double penalty = 0.0; // Moment, for penalty 926 double sum = 0.0, sum2 = 0.0; // Sum of kernel component 927 float min = INFINITY, max = -INFINITY; // Minimum and maximum kernel value 928 for (int v = kernel->yMin; v <= kernel->yMax; v++) { 929 for (int u = kernel->xMin; u <= kernel->xMax; u++) { 930 double value = kernel->kernel[v][u]; 931 if (false && zeroNull && (u == 0) && (v == 0)) { 932 value += 1.0; 933 } 934 double value2 = PS_SQR(value); 935 sum += value; 936 sum2 += value2; 937 penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v))); 938 min = PS_MIN(value, min); 939 max = PS_MAX(value, max); 940 } 941 } 942 penalty *= 1.0 / sum2; 943 944 if (1) { 945 fprintf(stderr, "min: %lf, max: %lf, moment: %lf, flux^2: %lf\n", min, max, penalty, sum2); 946 // psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, penalty); 947 } 948 949 return penalty; 753 950 } 754 951 -
trunk/psModules/src/imcombine/pmSubtractionStamps.h
r26893 r29004 24 24 psArray *flux; ///< Fluxes for possible stamps (or NULL) 25 25 int footprint; ///< Half-size of stamps 26 psKernel *window; ///< window function generated from ensemble of stamps27 26 float normFrac; ///< Fraction of flux in window for normalisation window 28 int normWindow; ///< Size of window for measuring normalisation 27 psKernel *window1; ///< window function generated from ensemble of stamps (input 1) 28 psKernel *window2; ///< window function generated from ensemble of stamps (input 2) 29 float normWindow1; ///< Size of window for measuring normalisation 30 float normWindow2; ///< Size of window for measuring normalisation 29 31 float sysErr; ///< Systematic error 30 32 float skyErr; ///< increase effective readnoise … … 195 197 bool pmSubtractionStampsResetStatus (pmSubtractionStampList *stamps); 196 198 199 200 bool pmSubtractionKernelPenaltiesStamp(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels); 201 bool pmSubtractionKernelPenalties(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels, int index); 202 float pmSubtractionKernelPenaltySingle(psKernel *kernel, bool zeroNull); 203 197 204 #endif -
trunk/psModules/src/imcombine/pmSubtractionVisual.c
r26893 r29004 21 21 22 22 #include "pmVisual.h" 23 #include "pmVisualUtils.h" 23 24 24 25 #include "pmHDU.h" … … 61 62 * @return true for success */ 62 63 bool pmSubtractionVisualPlotConvKernels(psImage *convKernels) { 63 if (!pmVisualIsVisual() || !plotConvKernels) return true; 64 65 if (!pmVisualTestLevel("ppsub.kernels", 1)) return true; 66 67 if (!plotConvKernels) return true; 68 64 69 if (!pmVisualInitWindow(&kapa1, "ppSub:Images")) { 65 70 return false; … … 75 80 @return true for success */ 76 81 bool pmSubtractionVisualPlotStamps(pmSubtractionStampList *stamps, pmReadout *ro) { 77 if (!pmVisualIsVisual() || !plotStamps) return true; 82 83 if (!pmVisualTestLevel("ppsub.stamps", 1)) return true; 84 85 if (!plotStamps) return true; 86 78 87 if (!pmVisualInitWindow (&kapa1, "ppSub:Images")) { 79 88 return false; … … 145 154 bool pmSubtractionVisualPlotLeastSquares (pmSubtractionStampList *stamps, bool dual) { 146 155 147 if (!pmVisualIsVisual() || !plotLeastSquares) return true; 156 if (!pmVisualTestLevel("ppsub.chisq", 1)) return true; 157 158 if (!plotLeastSquares) return true; 159 148 160 if (!pmVisualInitWindow (&kapa1, "PPSub:Images")) { 149 161 return false; … … 204 216 205 217 bool pmSubtractionVisualShowSubtraction(psImage *image, psImage *ref, psImage *sub) { 206 if (!pmVisualIsVisual() || !plotImage) return true; 218 219 if (!pmVisualTestLevel("ppsub.images.sub", 1)) return true; 220 221 if (!plotImage) return true; 222 207 223 if (!pmVisualInitWindow (&kapa1, "PPSub:Images")) { 208 224 return false; … … 218 234 bool pmSubtractionVisualShowKernels(pmSubtractionKernels *kernels) { 219 235 220 if (!pmVisualIsVisual()) return true; 236 if (!pmVisualTestLevel("ppsub.kernels.final", 1)) return true; 237 221 238 if (!pmVisualInitWindow (&kapa1, "PPSub:Images")) { 222 239 return false; … … 264 281 bool pmSubtractionVisualShowBasis(pmSubtractionStampList *stamps) { 265 282 266 if (!pmVisualIsVisual()) return true; 283 if (!pmVisualTestLevel("ppsub.basis", 1)) return true; 284 267 285 if (!pmVisualInitWindow (&kapa2, "ppSub:StampMasterImage")) { 268 286 return false; … … 425 443 bool pmSubtractionVisualShowFitInit(pmSubtractionStampList *stamps) { 426 444 427 if (!pmVisual IsVisual()) return true;445 if (!pmVisualTestLevel("ppsub.fit", 1)) return true; 428 446 429 447 // generate 4 storage images large enough to hold the N stamps: … … 462 480 bool pmSubtractionVisualShowFitAddStamp(psKernel *target, psKernel *source, psKernel *convolution, double background, double norm, int index) { 463 481 464 if (!pmVisual IsVisual()) return true;482 if (!pmVisualTestLevel("ppsub.stamp", 1)) return true; 465 483 466 484 double sum; … … 543 561 } 544 562 545 if (!pmVisualIsVisual()) return true; 563 if (!pmVisualTestLevel("ppsub.fit", 1)) return true; 564 546 565 if (!pmVisualInitWindow(&kapa1, "ppSub:Images")) return false; 547 566 if (!pmVisualInitWindow(&kapa2, "ppSub:Misc")) return false; … … 605 624 Graphdata graphdata; 606 625 607 if (!pmVisualIsVisual()) return true; 626 if (!pmVisualTestLevel("ppsub.fit", 1)) return true; 627 608 628 if (!pmVisualInitWindow(&kapa3, "ppSub:plots")) return false; 609 629
Note:
See TracChangeset
for help on using the changeset viewer.
