Changeset 26574
- Timestamp:
- Jan 12, 2010, 3:55:01 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionKernels.c
r26553 r26574 90 90 91 91 for (int i = 0, x = -size; x <= size; i++, x++) { 92 float xf = x / sigma;93 float z = -0.25*xf*xf;92 float xf = x / sigma; 93 float z = -0.25*xf*xf; 94 94 kernel->data.F32[i] = norm * p_pmSubtractionHermitianPolynomial(xf, order) * exp(z); 95 } 96 97 return kernel; 98 } 99 100 // Generate 1D convolution kernel for HERM (normalized for 2D) 101 psKernel *pmSubtractionKernelHERM_RADIAL(float sigma, // Gaussian width 102 int order, // Polynomial order 103 int size // Kernel half-size 104 ) 105 { 106 psKernel *kernel = psKernelAlloc(-size, size, -size, size); // 2D Kernel 107 108 // for now, we are only allowing equal orders and sigmas in X and Y 109 float nf = exp(lgamma(order + 1)); 110 float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI)); 111 112 // generate 2D radial hermitian 113 for (int v = -size; v <= size; v++) { 114 for (int u = -size; u <= size; u++) { 115 float r = hypot(u, v) / sigma; 116 float z = -0.25*r*r; 117 kernel->kernel[v][u] = norm * p_pmSubtractionHermitianPolynomial(r, order) * exp(z); 118 } 95 119 } 96 120 … … 132 156 kernels->preCalc->data[index] = NULL; 133 157 kernels->penalties->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v)); 134 psAssert(isfinite(kernels->penalties->data.F32[index]), "Invalid penalty"); 135 158 psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty"); 136 159 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v); 137 160 } … … 147 170 } 148 171 149 bool pmSubtractionKernelPreCalcNormalize (pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, int index, int size, int uOrder, int vOrder, float fwhm, bool AlardLuptonStyle ) {172 bool pmSubtractionKernelPreCalcNormalize (pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, int index, int size, int uOrder, int vOrder, float fwhm, bool AlardLuptonStyle, bool forceZeroNull) { 150 173 151 174 // Calculate moments 152 175 double moment = 0.0; // Moment, for penalty 153 176 for (int v = -size; v <= size; v++) { 154 for (int u = -size; u <= size; u++) {155 double value = preCalc->kernel->kernel[v][u];156 moment += PS_SQR(value) * PS_SQR((PS_SQR(u) + PS_SQR(v)));157 }177 for (int u = -size; u <= size; u++) { 178 double value = preCalc->kernel->kernel[v][u]; 179 moment += PS_SQR(value) * PS_SQR((PS_SQR(u) + PS_SQR(v))); 180 } 158 181 } 159 182 … … 169 192 170 193 for (int v = -size; v <= size; v++) { 171 for (int u = -size; u <= size; u++) {172 sum += preCalc->kernel->kernel[v][u];173 min = PS_MIN(preCalc->kernel->kernel[v][u], min);174 max = PS_MAX(preCalc->kernel->kernel[v][u], max);175 }194 for (int u = -size; u <= size; u++) { 195 sum += preCalc->kernel->kernel[v][u]; 196 min = PS_MIN(preCalc->kernel->kernel[v][u], min); 197 max = PS_MAX(preCalc->kernel->kernel[v][u], max); 198 } 176 199 } 177 200 #if 0 … … 181 204 // only even terms have non-zero sums 182 205 if ((uOrder % 2 == 0) && (vOrder % 2 == 0)) { 183 moment /= PS_SQR(sum); 206 moment /= PS_SQR(sum); 207 } else { 208 // XXX keep this? 209 moment = 0.0; 184 210 } 185 211 … … 189 215 190 216 if (AlardLuptonStyle && (uOrder % 2 == 0 && vOrder % 2 == 0)) { 191 zeroNull = true;217 zeroNull = true; 192 218 } 193 219 if (!AlardLuptonStyle && (uOrder == 0 && vOrder == 0)) { 194 zeroNull = true; 195 } 196 if ((uOrder % 2) || (vOrder % 2)) { 197 // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max); 198 scale2D = 1.0 / max; 199 scale1D = sqrt(scale2D); 200 } 201 202 psBinaryOp(preCalc->xKernel, preCalc->xKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 203 psBinaryOp(preCalc->yKernel, preCalc->yKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 220 zeroNull = true; 221 } 222 if (forceZeroNull) { 223 zeroNull = true; 224 } 225 if (!forceZeroNull && ((uOrder % 2) || (vOrder % 2))) { 226 // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max); 227 scale2D = 1.0 / max; 228 scale1D = sqrt(scale2D); 229 } 230 231 if (preCalc->xKernel) { 232 psBinaryOp(preCalc->xKernel, preCalc->xKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 233 } 234 if (preCalc->yKernel) { 235 psBinaryOp(preCalc->yKernel, preCalc->yKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 236 } 204 237 psBinaryOp(preCalc->kernel->image, preCalc->kernel->image, "*", psScalarAlloc(scale2D, PS_TYPE_F32)); 205 238 if (zeroNull) { 206 preCalc->kernel->kernel[0][0] -= 1.0;239 preCalc->kernel->kernel[0][0] -= 1.0; 207 240 } 208 241 … … 212 245 max = FLT_MIN; 213 246 for (int v = -size; v <= size; v++) { 214 for (int u = -size; u <= size; u++) {215 sum += preCalc->kernel->kernel[v][u];216 min = PS_MIN(preCalc->kernel->kernel[v][u], min);217 max = PS_MAX(preCalc->kernel->kernel[v][u], max);218 }247 for (int u = -size; u <= size; u++) { 248 sum += preCalc->kernel->kernel[v][u]; 249 min = PS_MIN(preCalc->kernel->kernel[v][u], min); 250 max = PS_MAX(preCalc->kernel->kernel[v][u], max); 251 } 219 252 } 220 253 fprintf(stderr, "%d mod: %lf, null: %f, min: %lf, max: %lf, scale: %f\n", index, sum, preCalc->kernel->kernel[0][0], min, max, scale2D); … … 225 258 kernels->v->data.S32[index] = vOrder; 226 259 if (kernels->preCalc->data[index]) { 227 psFree(kernels->preCalc->data[index]);260 psFree(kernels->preCalc->data[index]); 228 261 } 229 262 kernels->preCalc->data[index] = preCalc; 230 263 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 231 232 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, 233 fwhm, uOrder, vOrder, fabsf(moment)); 264 psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty"); 265 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, fabsf(moment)); 234 266 235 267 return true; … … 252 284 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 253 285 for (int i = 0; i < fwhmsIN->n; i++) { 254 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;255 psVectorAppend(fwhms, fwhmsIN->data.F32[i]);256 psVectorAppend(orders, ordersIN->data.S32[i]);286 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 287 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 288 psVectorAppend(orders, ordersIN->data.S32[i]); 257 289 } 258 290 … … 273 305 psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS kernel: %s,%d --> %d elements", 274 306 params, spatialOrder, num); 307 psFree(params); 308 309 // Set the kernel parameters 310 for (int i = 0, index = 0; i < numGaussians; i++) { 311 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 312 // Iterate over (u,v) order 313 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 314 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 315 316 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values 317 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 318 // pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], false, false); 319 } 320 } 321 } 322 323 return kernels; 324 } 325 326 pmSubtractionKernels *pmSubtractionKernelsISIS_RADIAL(int size, int spatialOrder, 327 const psVector *fwhmsIN, const psVector *ordersIN, 328 float penalty, pmSubtractionMode mode) 329 { 330 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 331 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 332 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 333 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 334 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 335 PS_ASSERT_INT_POSITIVE(size, NULL); 336 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 337 338 // check the requested fwhm values: any values <= 0.0 should be dropped 339 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 340 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 341 for (int i = 0; i < fwhmsIN->n; i++) { 342 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 343 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 344 psVectorAppend(orders, ordersIN->data.S32[i]); 345 } 346 347 int numGaussians = fwhms->n; // Number of Gaussians 348 349 int num = 0; // Number of basis functions 350 psString params = NULL; // List of parameters 351 for (int i = 0; i < numGaussians; i++) { 352 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 353 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 354 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 355 num += (11 - gaussOrder - 1); // include all higher order radial terms 356 } 357 358 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS_RADIAL, size, spatialOrder, penalty, mode); // The kernels 359 psStringAppend(&kernels->description, "ISIS_RADIAL(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 360 361 psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS_RADIAL kernel: %s,%d --> %d elements", params, spatialOrder, num); 275 362 psFree(params); 276 363 … … 282 369 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 283 370 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values 284 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);371 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 285 372 } 286 373 } 287 } 288 374 for (int order = orders->data.S32[i] + 1; order < 11; order ++, index ++) { 375 // XXX modify size for hermitians to account for sqrt(2) in Hermitian definition (relative to ISIS Gaussian) 376 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS_RADIAL, order, order, size, sigma / sqrt(2.0)); // structure to hold precalculated values 377 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, order, order, fwhms->data.F32[i], true, true); 378 } 379 } 289 380 return kernels; 290 381 } 291 382 292 383 pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder, 293 const psVector *fwhmsIN, const psVector *ordersIN,294 float penalty, pmSubtractionMode mode)384 const psVector *fwhmsIN, const psVector *ordersIN, 385 float penalty, pmSubtractionMode mode) 295 386 { 296 387 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); … … 306 397 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 307 398 for (int i = 0; i < fwhmsIN->n; i++) { 308 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;309 psVectorAppend(fwhms, fwhmsIN->data.F32[i]);310 psVectorAppend(orders, ordersIN->data.S32[i]);399 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 400 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 401 psVectorAppend(orders, ordersIN->data.S32[i]); 311 402 } 312 403 … … 334 425 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 335 426 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 336 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);427 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 337 428 } 338 429 } … … 343 434 344 435 pmSubtractionKernels *pmSubtractionKernelsDECONV_HERM(int size, int spatialOrder, 345 const psVector *fwhmsIN, const psVector *ordersIN,346 float penalty, pmSubtractionMode mode)436 const psVector *fwhmsIN, const psVector *ordersIN, 437 float penalty, pmSubtractionMode mode) 347 438 { 348 439 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); … … 358 449 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 359 450 for (int i = 0; i < fwhmsIN->n; i++) { 360 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;361 psVectorAppend(fwhms, fwhmsIN->data.F32[i]);362 psVectorAppend(orders, ordersIN->data.S32[i]);451 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 452 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 453 psVectorAppend(orders, ordersIN->data.S32[i]); 363 454 } 364 455 … … 397 488 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 398 489 399 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel400 psKernel *kernelTarget = preCalc->kernel;490 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel 491 psKernel *kernelTarget = preCalc->kernel; 401 492 preCalc->kernel = pmSubtractionDeconvolveKernel(kernelTarget, kernelGauss); // Kernel 402 493 403 // XXX do we use Alard-Lupton normalization (last param true) or not?404 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);405 406 // XXXX test demo that deconvolved kernel is valid494 // XXX do we use Alard-Lupton normalization (last param true) or not? 495 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 496 497 // XXXX test demo that deconvolved kernel is valid 407 498 # if 1 408 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss);409 psArrayAdd (deconKernels, 100, kernelConv);410 psFree (kernelConv);411 412 if (!uOrder && !vOrder){413 pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv);414 }499 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss); 500 psArrayAdd (deconKernels, 100, kernelConv); 501 psFree (kernelConv); 502 503 if (!uOrder && !vOrder){ 504 pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv); 505 } 415 506 # endif 416 507 } … … 421 512 psImage *dot = psImageAlloc(deconKernels->n, deconKernels->n, PS_TYPE_F32); 422 513 for (int i = 0; i < deconKernels->n; i++) { 423 for (int j = 0; j <= i; j++) {424 psImage *t1 = deconKernels->data[i];425 psImage *t2 = deconKernels->data[j];426 427 double sum = 0.0;428 for (int iy = 0; iy < t1->numRows; iy++) {429 for (int ix = 0; ix < t1->numCols; ix++) {430 sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix];431 }432 }433 dot->data.F32[j][i] = sum;434 dot->data.F32[i][j] = sum;435 }514 for (int j = 0; j <= i; j++) { 515 psImage *t1 = deconKernels->data[i]; 516 psImage *t2 = deconKernels->data[j]; 517 518 double sum = 0.0; 519 for (int iy = 0; iy < t1->numRows; iy++) { 520 for (int ix = 0; ix < t1->numCols; ix++) { 521 sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix]; 522 } 523 } 524 dot->data.F32[j][i] = sum; 525 dot->data.F32[i][j] = sum; 526 } 436 527 } 437 528 pmSubtractionVisualShowSubtraction (dot, NULL, NULL); … … 460 551 kernels->v = psVectorAlloc(numBasisFunctions, PS_TYPE_S32); 461 552 kernels->widths = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 553 kernels->uStop = NULL; 554 kernels->vStop = NULL; 462 555 kernels->preCalc = psArrayAlloc(numBasisFunctions); 463 556 kernels->penalty = penalty; 464 557 kernels->penalties = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 465 kernels->uStop = NULL;466 kernels->vStop = NULL;467 558 kernels->size = size; 468 559 kernels->inner = 0; … … 474 565 kernels->solution1 = NULL; 475 566 kernels->solution2 = NULL; 567 kernels->mean = NAN; 568 kernels->rms = NAN; 569 kernels->numStamps = 0; 570 571 kernels->fSigResMean = NAN; 572 kernels->fSigResStdev = NAN; 573 kernels->fMaxResMean = NAN; 574 kernels->fMaxResStdev = NAN; 575 kernels->fMinResMean = NAN; 576 kernels->fMinResStdev = NAN; 476 577 477 578 return kernels; … … 486 587 switch (type) { 487 588 case PM_SUBTRACTION_KERNEL_ISIS: 488 preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size);489 preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size);490 preCalc->uCoords = NULL;491 preCalc->vCoords = NULL;492 preCalc->poly = NULL;493 break;589 preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size); 590 preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size); 591 preCalc->uCoords = NULL; 592 preCalc->vCoords = NULL; 593 preCalc->poly = NULL; 594 break; 494 595 case PM_SUBTRACTION_KERNEL_HERM: 495 preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size); 496 preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size); 497 preCalc->uCoords = NULL; 498 preCalc->vCoords = NULL; 499 preCalc->poly = NULL; 500 break; 501 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 502 preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size); 503 preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size); 504 preCalc->uCoords = NULL; 505 preCalc->vCoords = NULL; 506 preCalc->poly = NULL; 507 break; 596 preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size); 597 preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size); 598 preCalc->uCoords = NULL; 599 preCalc->vCoords = NULL; 600 preCalc->poly = NULL; 601 break; 508 602 case PM_SUBTRACTION_KERNEL_RINGS: 509 // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure 510 // we allocate these vectors here, but leave the kernel generation to the main function 511 preCalc->xKernel = NULL; 512 preCalc->yKernel = NULL; 513 preCalc->kernel = NULL; 514 preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords 515 preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords 516 preCalc->poly = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial 517 return preCalc; 603 // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure 604 // we allocate these vectors here, but leave the kernel generation to the main function 605 preCalc->xKernel = NULL; 606 preCalc->yKernel = NULL; 607 preCalc->kernel = NULL; 608 preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords 609 preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords 610 preCalc->poly = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial 611 return preCalc; 612 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 613 preCalc->kernel = pmSubtractionKernelHERM_RADIAL(sigma, uOrder, size); 614 preCalc->xKernel = NULL; 615 preCalc->yKernel = NULL; 616 preCalc->uCoords = NULL; 617 preCalc->vCoords = NULL; 618 preCalc->poly = NULL; 619 return preCalc; 518 620 default: 519 psAbort("programming error: invalid type for PreCalc kernel");621 psAbort("programming error: invalid type for PreCalc kernel"); 520 622 } 521 623 … … 524 626 // generate 2D kernel from 1D realizations 525 627 for (int v = -size, y = 0; v <= size; v++, y++) { 526 for (int u = -size, x = 0; u <= size; u++, x++) {527 preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel528 }529 } 530 628 for (int u = -size, x = 0; u <= size; u++, x++) { 629 preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel 630 } 631 } 632 531 633 return preCalc; 532 634 } … … 753 855 } 754 856 755 // Grid United with Normal Kernel 857 // Grid United with Normal Kernel [description: GUNK=ISIS(...)+POIS(...)] 756 858 pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *fwhms, 757 859 const psVector *orders, int inner, float penalty, … … 856 958 for (int vOrder = 0; vOrder <= (i == 0 ? 0 : ringsOrder - uOrder); vOrder++, index++) { 857 959 858 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0);960 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0); 859 961 double moment = 0.0; // Moment, for penalty 860 962 … … 862 964 // Central pixel is easy 863 965 preCalc->uCoords->data.S32[0] = 0; 864 preCalc->vCoords->data.S32[0] = 0;966 preCalc->vCoords->data.S32[0] = 0; 865 967 preCalc->poly->data.F32[0] = 1.0; 866 968 preCalc->uCoords->n = 1; 867 preCalc->vCoords->n = 1;868 preCalc->poly->n = 1;969 preCalc->vCoords->n = 1; 970 preCalc->poly->n = 1; 869 971 radiusLast = 0; 870 972 moment = 0.0; … … 923 1025 kernels->v->data.S32[index] = vOrder; 924 1026 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 925 if (!isfinite(kernels->penalties->data.F32[index])) {926 psAbort ("invalid penalty");927 }1027 if (!isfinite(kernels->penalties->data.F32[index])) { 1028 psAbort ("invalid penalty"); 1029 } 928 1030 929 1031 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d\n", index, … … 946 1048 case PM_SUBTRACTION_KERNEL_ISIS: 947 1049 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode); 1050 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1051 return pmSubtractionKernelsISIS_RADIAL(size, spatialOrder, fwhms, orders, penalty, mode); 948 1052 case PM_SUBTRACTION_KERNEL_HERM: 949 1053 return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, mode); … … 1012 1116 float penalty = 0.0; // Penalty for wideness 1013 1117 1014 // ISIS, HERM, and DECONV_HERM have the same description layout 1015 if (!strncmp(description, "ISIS", 4) || !strcmp (description, "HERM") || !strcmp (description, "DECONV_HERM")) { 1016 // XXX Support for GUNK (not yet supported) 1017 if (strstr(description, "+POIS")) { 1018 type = PM_SUBTRACTION_KERNEL_GUNK; 1019 psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description); 1020 } 1021 1022 type = pmSubtractionKernelsTypeFromString (description); 1023 psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must be ISIS, HERM or DECONV_HERM"); 1024 1025 char *ptr = NULL; 1026 switch (type) { 1027 case PM_SUBTRACTION_KERNEL_ISIS: 1028 case PM_SUBTRACTION_KERNEL_HERM: 1029 ptr = (char*) description + 5; // Eat "ISIS(" or "HERM(" 1030 break; 1031 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1032 ptr = (char*) description + 12; // Eat "DECONV_HERM(" 1033 break; 1034 default: 1035 psAbort("programming error: invalid kernel type"); 1036 } 1037 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 1038 1039 // Count the number of Gaussians 1040 int numGauss = 0; 1041 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 1042 numGauss++; 1043 } 1044 1045 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 1046 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 1047 1048 for (int i = 0; i < numGauss; i++) { 1049 ptr++; // Eat the '(' 1050 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 1051 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 1052 } 1053 1054 ptr++; // Eat ',' 1055 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 1056 penalty = parseStringFloat(ptr); 1057 1058 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 1059 } 1060 1061 if (strncmp(description, "RINGS", 5) == 0) { 1062 type = PM_SUBTRACTION_KERNEL_RINGS; 1063 char *ptr = (char*)description + 6; 1118 // currently known descriptions: 1119 // ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), SPAM(...), 1120 // FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 1121 // the descriptive name is the set of characters before the ( 1122 1123 type = pmSubtractionKernelsTypeFromString (description); 1124 char *ptr = strchr(description, '('); 1125 psAssert (ptr, "description is missing kernel parameters"); 1126 1127 switch (type) { 1128 case PM_SUBTRACTION_KERNEL_ISIS: 1129 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1130 case PM_SUBTRACTION_KERNEL_HERM: 1131 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1132 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 1133 1134 // Count the number of Gaussians 1135 int numGauss = 0; 1136 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 1137 numGauss++; 1138 } 1139 1140 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 1141 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 1142 1143 for (int i = 0; i < numGauss; i++) { 1144 ptr++; // Eat the '(' 1145 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 1146 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 1147 } 1148 1149 ptr++; // Eat ',' 1150 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 1151 penalty = parseStringFloat(ptr); 1152 1153 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 1154 1155 case PM_SUBTRACTION_KERNEL_RINGS: 1064 1156 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 1065 1157 PARSE_STRING_NUMBER(inner, ptr, ',', parseStringInt); … … 1067 1159 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 1068 1160 PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt); 1069 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 1070 } 1071 1072 psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported."); 1073 1074 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, 1075 inner, binning, ringsOrder, penalty, mode); 1076 } 1077 1078 1161 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 1162 default: 1163 psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported."); 1164 } 1165 return NULL; 1166 } 1167 1168 1169 // the input string can either be just the name or the description string. Currently known 1170 // descriptions: ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), 1171 // SPAM(...), FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 1079 1172 pmSubtractionKernelsType pmSubtractionKernelsTypeFromString(const char *type) 1080 1173 { 1081 if (strcasecmp(type, "POIS") == 0) { 1174 // for a bare name (ISIS, HERM), use the full string length. 1175 // otherwise, use the length up to the first '(' 1176 int nameLength = strlen(type); 1177 char *ptr = strchr(type, '('); 1178 if (ptr) { 1179 nameLength = ptr - type; 1180 } 1181 1182 if (strncasecmp(type, "POIS", nameLength) == 0) { 1082 1183 return PM_SUBTRACTION_KERNEL_POIS; 1083 1184 } 1084 if (str casecmp(type, "ISIS") == 0) {1185 if (strncasecmp(type, "ISIS", nameLength) == 0) { 1085 1186 return PM_SUBTRACTION_KERNEL_ISIS; 1086 1187 } 1087 if (strcasecmp(type, "HERM") == 0) { 1188 if (strncasecmp(type, "ISIS_RADIAL", nameLength) == 0) { 1189 return PM_SUBTRACTION_KERNEL_ISIS_RADIAL; 1190 } 1191 if (strncasecmp(type, "HERM", nameLength) == 0) { 1088 1192 return PM_SUBTRACTION_KERNEL_HERM; 1089 1193 } 1090 if (str casecmp(type, "DECONV_HERM") == 0) {1194 if (strncasecmp(type, "DECONV_HERM", nameLength) == 0) { 1091 1195 return PM_SUBTRACTION_KERNEL_DECONV_HERM; 1092 1196 } 1093 if (str casecmp(type, "SPAM") == 0) {1197 if (strncasecmp(type, "SPAM", nameLength) == 0) { 1094 1198 return PM_SUBTRACTION_KERNEL_SPAM; 1095 1199 } 1096 if (str casecmp(type, "FRIES") == 0) {1200 if (strncasecmp(type, "FRIES", nameLength) == 0) { 1097 1201 return PM_SUBTRACTION_KERNEL_FRIES; 1098 1202 } 1099 if (str casecmp(type, "GUNK") == 0) {1203 if (strncasecmp(type, "GUNK", nameLength) == 0) { 1100 1204 return PM_SUBTRACTION_KERNEL_GUNK; 1101 1205 } 1102 if (strcasecmp(type, "RINGS") == 0) { 1206 // note that GUNK has a somewhat different description 1207 if (strncasecmp(type, "GUNK=ISIS", nameLength) == 0) { 1208 return PM_SUBTRACTION_KERNEL_GUNK; 1209 } 1210 if (strncasecmp(type, "RINGS", nameLength) == 0) { 1103 1211 return PM_SUBTRACTION_KERNEL_RINGS; 1104 1212 }
Note:
See TracChangeset
for help on using the changeset viewer.
