Changeset 26893 for trunk/psModules/src/imcombine/pmSubtractionKernels.c
- Timestamp:
- Feb 10, 2010, 7:34:39 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtractionKernels.c
r26156 r26893 10 10 #include "pmSubtraction.h" 11 11 #include "pmSubtractionKernels.h" 12 #include "pmSubtractionHermitian.h" 13 #include "pmSubtractionDeconvolve.h" 14 #include "pmSubtractionVisual.h" 12 15 13 16 #define RINGS_BUFFER 10 // Buffer size for RINGS data 14 15 17 16 18 // Free function for pmSubtractionKernels … … 27 29 psFree(kernels->solution1); 28 30 psFree(kernels->solution2); 31 psFree(kernels->sampleStamps); 32 } 33 34 // Free function for pmSubtractionPreCalcKernel 35 static void pmSubtractionKernelPreCalcFree(pmSubtractionKernelPreCalc *kernel) 36 { 37 psFree(kernel->xKernel); 38 psFree(kernel->yKernel); 39 psFree(kernel->kernel); 40 41 psFree(kernel->uCoords); 42 psFree(kernel->vCoords); 43 psFree(kernel->poly); 29 44 } 30 45 … … 45 60 46 61 // Generate 1D convolution kernel for ISIS 47 static psVector *subtractionKernelISIS(float sigma, // Gaussian width62 psVector *pmSubtractionKernelISIS(float sigma, // Gaussian width 48 63 int order, // Polynomial order 49 64 int size // Kernel half-size … … 57 72 for (int i = 0, x = -size; x <= size; i++, x++) { 58 73 kernel->data.F32[i] = norm * power(x, order) * expf(expNorm * PS_SQR(x)); 74 } 75 76 return kernel; 77 } 78 79 // Generate 1D convolution kernel for HERM (normalized for 2D) 80 psVector *pmSubtractionKernelHERM(float sigma, // Gaussian width 81 int order, // Polynomial order 82 int size // Kernel half-size 83 ) 84 { 85 int fullSize = 2 * size + 1; // Full size of kernel 86 psVector *kernel = psVectorAlloc(fullSize, PS_TYPE_F32); // Kernel to return 87 88 // for now, we are only allowing equal orders and sigmas in X and Y 89 float nf = exp(lgamma(order + 1)); 90 float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI)); 91 92 for (int i = 0, x = -size; x <= size; i++, x++) { 93 float xf = x / sigma; 94 float z = -0.25*xf*xf; 95 kernel->data.F32[i] = norm * p_pmSubtractionHermitianPolynomial(xf, order) * exp(z); 96 } 97 98 return kernel; 99 } 100 101 // Generate 1D convolution kernel for HERM (normalized for 2D) 102 psKernel *pmSubtractionKernelHERM_RADIAL(float sigma, // Gaussian width 103 int order, // Polynomial order 104 int size // Kernel half-size 105 ) 106 { 107 psKernel *kernel = psKernelAlloc(-size, size, -size, size); // 2D Kernel 108 109 // for now, we are only allowing equal orders and sigmas in X and Y 110 float nf = exp(lgamma(order + 1)); 111 float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI)); 112 113 // generate 2D radial hermitian 114 for (int v = -size; v <= size; v++) { 115 for (int u = -size; u <= size; u++) { 116 float r = hypot(u, v) / sigma; 117 float z = -0.25*r*r; 118 kernel->kernel[v][u] = norm * p_pmSubtractionHermitianPolynomial(r, order) * exp(z); 119 } 59 120 } 60 121 … … 96 157 kernels->preCalc->data[index] = NULL; 97 158 kernels->penalties->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v)); 98 159 psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty"); 99 160 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v); 100 161 } … … 110 171 } 111 172 173 bool pmSubtractionKernelPreCalcNormalize(pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, 174 int index, int size, int uOrder, int vOrder, float fwhm, 175 bool AlardLuptonStyle, bool forceZeroNull) 176 { 177 // we have 4 cases here: 178 // 1) for odd functions, normalize the kernel by the maximum swing / Npix 179 // 2) for even functions, normalize the kernel to unity 180 // 3) for alard-lupton style normalization, subtract 1 from the 0,0 pixel for all even functions 181 // 4) for deconvolved hermitians, subtract 1 from the 0,0 pixel for the 0,0 function(s) 182 183 // Calculate moments 184 double penalty = 0.0; // Moment, for penalty 185 double sum = 0.0, sum2 = 0.0; // Sum of kernel component 186 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++) { 189 double value = preCalc->kernel->kernel[v][u]; 190 double value2 = PS_SQR(value); 191 sum += value; 192 sum2 += value2; 193 penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v))); 194 min = PS_MIN(value, min); 195 max = PS_MAX(value, max); 196 } 197 } 198 199 #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); 201 #endif 202 203 bool zeroNull = false; // Zero out using the null position? 204 float scale2D = NAN; // Scaling for 2-D kernels 205 206 if (AlardLuptonStyle) { 207 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 208 // Even functions: normalise to unit sum and subtract null pixel so that sum is zero 209 scale2D = 1.0 / fabs(sum); 210 zeroNull = true; 211 } else { 212 // Odd functions: choose normalisation so that parameters have about the same strength as for even 213 // functions, no subtraction of null pixel because the sum is already (near) zero 214 scale2D = 1.0 / sqrt(sum2); 215 zeroNull = false; 216 } 217 } 218 219 if (!AlardLuptonStyle && (uOrder == 0 && vOrder == 0)) { 220 zeroNull = true; 221 } 222 if (forceZeroNull) { 223 // Force rescaling and subtraction of null pixel even though the order doesn't indicate it's even 224 scale2D = 1.0 / fabs(sum); 225 zeroNull = true; 226 } 227 if (!forceZeroNull && ((uOrder % 2) || (vOrder % 2))) { 228 // Odd function 229 scale2D = 1.0 / sqrt(sum2); 230 } 231 232 float scale1D = sqrtf(scale2D); // Scaling for 1-D kernels 233 if (preCalc->xKernel) { 234 psBinaryOp(preCalc->xKernel, preCalc->xKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 235 } 236 if (preCalc->yKernel) { 237 psBinaryOp(preCalc->yKernel, preCalc->yKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32)); 238 } 239 240 psBinaryOp(preCalc->kernel->image, preCalc->kernel->image, "*", psScalarAlloc(scale2D, PS_TYPE_F32)); 241 penalty *= 1.0 / sum2; 242 243 if (zeroNull) { 244 preCalc->kernel->kernel[0][0] -= 1.0; 245 } 246 247 #if 0 248 { 249 double sum = 0.0; // Sum of kernel component 250 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]; 254 min = PS_MIN(preCalc->kernel->kernel[v][u], min); 255 max = PS_MAX(preCalc->kernel->kernel[v][u], max); 256 } 257 } 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); 259 } 260 #endif 261 262 kernels->widths->data.F32[index] = fwhm; 263 kernels->u->data.S32[index] = uOrder; 264 kernels->v->data.S32[index] = vOrder; 265 if (kernels->preCalc->data[index]) { 266 psFree(kernels->preCalc->data[index]); 267 } 268 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); 272 273 return true; 274 } 275 112 276 pmSubtractionKernels *p_pmSubtractionKernelsRawISIS(int size, int spatialOrder, 113 const psVector *fwhms , const psVector *orders,114 float penalty, p mSubtractionMode mode)115 { 116 PS_ASSERT_VECTOR_NON_NULL(fwhms , NULL);117 PS_ASSERT_VECTOR_TYPE(fwhms , PS_TYPE_F32, NULL);118 PS_ASSERT_VECTOR_NON_NULL(orders , NULL);119 PS_ASSERT_VECTOR_TYPE(orders , PS_TYPE_S32, NULL);120 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhms , orders, NULL);277 const psVector *fwhmsIN, const psVector *ordersIN, 278 float penalty, psRegion bounds, pmSubtractionMode mode) 279 { 280 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 281 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 282 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 283 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 284 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 121 285 PS_ASSERT_INT_POSITIVE(size, NULL); 122 286 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 287 288 // check the requested fwhm values: any values <= 0.0 should be dropped 289 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 290 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 291 for (int i = 0; i < fwhmsIN->n; i++) { 292 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 293 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 294 psVectorAppend(orders, ordersIN->data.S32[i]); 295 } 123 296 124 297 int numGaussians = fwhms->n; // Number of Gaussians … … 133 306 134 307 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS, size, 135 spatialOrder, penalty, mode); // The kernels308 spatialOrder, penalty, bounds, mode); // Kernels 136 309 psStringAppend(&kernels->description, "ISIS(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 137 310 … … 141 314 142 315 // Set the kernel parameters 143 int fullSize = 2 * size + 1; // Full size of kernels144 316 for (int i = 0, index = 0; i < numGaussians; i++) { 145 317 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma … … 147 319 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 148 320 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 149 psArray *preCalc = psArrayAlloc(3); // Array to hold precalculated values 150 psVector *xKernel = preCalc->data[0] = subtractionKernelISIS(sigma, uOrder, size); // x Kernel 151 psVector *yKernel = preCalc->data[1] = subtractionKernelISIS(sigma, vOrder, size); // y Kernel 152 psKernel *kernel = preCalc->data[2] = psKernelAlloc(-size, size, -size, size); // Kernel 153 154 // Calculate moments 155 double moment = 0.0; // Moment, for penalty 156 for (int v = -size, y = 0; v <= size; v++, y++) { 157 for (int u = -size, x = 0; u <= size; u++, x++) { 158 double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel 159 kernel->kernel[v][u] = value; 160 moment += value * PS_SQR((PS_SQR(u) + PS_SQR(v))); 161 } 321 322 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); 325 } 326 } 327 } 328 329 return kernels; 330 } 331 332 pmSubtractionKernels *pmSubtractionKernelsISIS_RADIAL(int size, int spatialOrder, 333 const psVector *fwhmsIN, const psVector *ordersIN, 334 float penalty, psRegion bounds, pmSubtractionMode mode) 335 { 336 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 337 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 338 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 339 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 340 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 341 PS_ASSERT_INT_POSITIVE(size, NULL); 342 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 343 344 // check the requested fwhm values: any values <= 0.0 should be dropped 345 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 346 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 347 for (int i = 0; i < fwhmsIN->n; i++) { 348 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 349 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 350 psVectorAppend(orders, ordersIN->data.S32[i]); 351 } 352 353 int numGaussians = fwhms->n; // Number of Gaussians 354 355 int num = 0; // Number of basis functions 356 psString params = NULL; // List of parameters 357 for (int i = 0; i < numGaussians; i++) { 358 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 359 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 360 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 361 num += (11 - gaussOrder - 1); // include all higher order radial terms 362 } 363 364 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS_RADIAL, size, 365 spatialOrder, penalty, bounds, mode); // Kernels 366 psStringAppend(&kernels->description, "ISIS_RADIAL(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 367 368 psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS_RADIAL kernel: %s,%d --> %d elements", params, spatialOrder, num); 369 psFree(params); 370 371 // Set the kernel parameters 372 for (int i = 0, index = 0; i < numGaussians; i++) { 373 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 374 // Iterate over (u,v) order 375 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 376 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 377 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values 378 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 379 } 380 } 381 for (int order = orders->data.S32[i] + 1; order < 11; order ++, index ++) { 382 // XXX modify size for hermitians to account for sqrt(2) in Hermitian definition (relative to ISIS Gaussian) 383 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS_RADIAL, order, order, size, sigma / sqrt(2.0)); // structure to hold precalculated values 384 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, order, order, fwhms->data.F32[i], true, true); 385 } 386 } 387 return kernels; 388 } 389 390 pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder, 391 const psVector *fwhmsIN, const psVector *ordersIN, 392 float penalty, psRegion bounds, pmSubtractionMode mode) 393 { 394 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 395 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 396 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 397 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 398 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 399 PS_ASSERT_INT_POSITIVE(size, NULL); 400 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 401 402 // check the requested fwhm values: any values <= 0.0 should be dropped 403 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 404 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 405 for (int i = 0; i < fwhmsIN->n; i++) { 406 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 407 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 408 psVectorAppend(orders, ordersIN->data.S32[i]); 409 } 410 411 int numGaussians = fwhms->n; // Number of Gaussians 412 413 int num = 0; // Number of basis functions 414 psString params = NULL; // List of parameters 415 for (int i = 0; i < numGaussians; i++) { 416 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 417 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 418 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 419 } 420 421 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_HERM, size, 422 spatialOrder, penalty, bounds, mode); // Kernels 423 psStringAppend(&kernels->description, "HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 424 425 psLogMsg("psModules.imcombine", PS_LOG_INFO, "HERM kernel: %s,%d --> %d elements", 426 params, spatialOrder, num); 427 psFree(params); 428 429 // Set the kernel parameters 430 for (int i = 0, index = 0; i < numGaussians; i++) { 431 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 432 // Iterate over (u,v) order 433 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 434 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 435 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 436 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 437 } 438 } 439 } 440 441 return kernels; 442 } 443 444 pmSubtractionKernels *pmSubtractionKernelsDECONV_HERM(int size, int spatialOrder, 445 const psVector *fwhmsIN, const psVector *ordersIN, 446 float penalty, psRegion bounds, pmSubtractionMode mode) 447 { 448 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 449 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 450 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 451 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 452 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 453 PS_ASSERT_INT_POSITIVE(size, NULL); 454 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 455 456 // check the requested fwhm values: any values <= 0.0 should be dropped 457 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 458 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 459 for (int i = 0; i < fwhmsIN->n; i++) { 460 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 461 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 462 psVectorAppend(orders, ordersIN->data.S32[i]); 463 } 464 465 int numGaussians = fwhms->n; // Number of Gaussians 466 467 int num = 0; // Number of basis functions 468 psString params = NULL; // List of parameters 469 for (int i = 0; i < numGaussians; i++) { 470 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 471 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 472 num += PS_SQR(gaussOrder + 1); 473 } 474 475 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_DECONV_HERM, size, 476 spatialOrder, penalty, bounds, mode); // Kernels 477 psStringAppend(&kernels->description, "DECONV_HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 478 479 psLogMsg("psModules.imcombine", PS_LOG_INFO, "DECONVOLVED HERM kernel: %s,%d --> %d elements", params, spatialOrder, num); 480 psFree(params); 481 482 // XXXXX hard-wired reference sigma for now of 1.7 pix (== 4.0 pix fwhm == 1.0 arcsec in simtest) 483 // generate the Gaussian deconvolution kernel 484 # define DECONV_SIGMA 1.6 485 psKernel *kernelGauss = pmSubtractionDeconvolveGauss (size, DECONV_SIGMA); 486 487 # if 1 488 psArray *deconKernels = psArrayAllocEmpty(100); 489 # endif 490 491 // Set the kernel parameters 492 for (int i = 0, index = 0; i < numGaussians; i++) { 493 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 494 // Iterate over (u,v) order 495 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 496 for (int vOrder = 0; vOrder <= orders->data.S32[i]; vOrder++, index++) { 497 498 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 499 500 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel 501 psKernel *kernelTarget = preCalc->kernel; 502 preCalc->kernel = pmSubtractionDeconvolveKernel(kernelTarget, kernelGauss); // Kernel 503 504 // XXX do we use Alard-Lupton normalization (last param true) or not? 505 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false); 506 507 // XXXX test demo that deconvolved kernel is valid 508 # if 1 509 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss); 510 psArrayAdd (deconKernels, 100, kernelConv); 511 psFree (kernelConv); 512 513 if (!uOrder && !vOrder){ 514 pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv); 162 515 } 163 164 // Normalise sum of kernel component to unity for even functions 165 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 166 double sum = 0.0; // Sum of kernel component 167 for (int v = 0; v < fullSize; v++) { 168 for (int u = 0; u < fullSize; u++) { 169 sum += xKernel->data.F32[u] * yKernel->data.F32[v]; 170 } 171 } 172 sum = 1.0 / sqrt(sum); 173 psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 174 psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 175 psBinaryOp(kernel->image, kernel->image, "*", psScalarAlloc(PS_SQR(sum), PS_TYPE_F32)); 176 kernel->kernel[0][0] -= 1.0; 177 moment *= PS_SQR(sum); 516 # endif 517 } 518 } 519 } 520 521 # if 1 522 psImage *dot = psImageAlloc(deconKernels->n, deconKernels->n, PS_TYPE_F32); 523 for (int i = 0; i < deconKernels->n; i++) { 524 for (int j = 0; j <= i; j++) { 525 psImage *t1 = deconKernels->data[i]; 526 psImage *t2 = deconKernels->data[j]; 527 528 double sum = 0.0; 529 for (int iy = 0; iy < t1->numRows; iy++) { 530 for (int ix = 0; ix < t1->numCols; ix++) { 531 sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix]; 178 532 } 179 180 181 #if 0182 double sum = 0.0; // Sum of kernel component183 for (int v = -size; v <= size; v++) {184 for (int u = -size; u <= size; u++) {185 sum += kernel->kernel[v][u];186 }187 }188 fprintf(stderr, "%d sum: %lf\n", index, sum);189 #endif190 191 kernels->widths->data.F32[index] = fwhms->data.F32[i];192 kernels->u->data.S32[index] = uOrder;193 kernels->v->data.S32[index] = vOrder;194 if (kernels->preCalc->data[index]) {195 psFree(kernels->preCalc->data[index]);196 }197 kernels->preCalc->data[index] = preCalc;198 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);199 200 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index,201 fwhms->data.F32[i], uOrder, vOrder, fabsf(moment));202 533 } 203 } 204 } 534 dot->data.F32[j][i] = sum; 535 dot->data.F32[i][j] = sum; 536 } 537 } 538 pmSubtractionVisualShowSubtraction (dot, NULL, NULL); 539 psFree (dot); 540 psFree (deconKernels); 541 # endif 205 542 206 543 return kernels; … … 212 549 213 550 pmSubtractionKernels *pmSubtractionKernelsAlloc(int numBasisFunctions, pmSubtractionKernelsType type, 214 int size, int spatialOrder, float penalty, 551 int size, int spatialOrder, float penalty, psRegion bounds, 215 552 pmSubtractionMode mode) 216 553 { … … 224 561 kernels->v = psVectorAlloc(numBasisFunctions, PS_TYPE_S32); 225 562 kernels->widths = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 563 kernels->uStop = NULL; 564 kernels->vStop = NULL; 565 kernels->xMin = bounds.x0; 566 kernels->xMax = bounds.x1; 567 kernels->yMin = bounds.y0; 568 kernels->yMax = bounds.y1; 226 569 kernels->preCalc = psArrayAlloc(numBasisFunctions); 227 570 kernels->penalty = penalty; 228 571 kernels->penalties = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 229 kernels->uStop = NULL;230 kernels->vStop = NULL;231 572 kernels->size = size; 232 573 kernels->inner = 0; … … 234 575 kernels->bgOrder = 0; 235 576 kernels->mode = mode; 236 kernels->numCols = 0;237 kernels->numRows = 0;238 577 kernels->solution1 = NULL; 239 578 kernels->solution2 = NULL; 579 kernels->mean = NAN; 580 kernels->rms = NAN; 581 kernels->numStamps = 0; 582 kernels->sampleStamps = NULL; 583 584 kernels->fSigResMean = NAN; 585 kernels->fSigResStdev = NAN; 586 kernels->fMaxResMean = NAN; 587 kernels->fMaxResStdev = NAN; 588 kernels->fMinResMean = NAN; 589 kernels->fMinResStdev = NAN; 240 590 241 591 return kernels; 242 592 } 243 593 244 pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder, float penalty, 594 pmSubtractionKernelPreCalc *pmSubtractionKernelPreCalcAlloc(pmSubtractionKernelsType type, int uOrder, int vOrder, int size, float sigma) { 595 596 pmSubtractionKernelPreCalc *preCalc = psAlloc(sizeof(pmSubtractionKernelPreCalc)); // Kernels, to return 597 psMemSetDeallocator(preCalc, (psFreeFunc)pmSubtractionKernelPreCalcFree); 598 599 // 1D kernel realizations: 600 switch (type) { 601 case PM_SUBTRACTION_KERNEL_ISIS: 602 preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size); 603 preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size); 604 preCalc->uCoords = NULL; 605 preCalc->vCoords = NULL; 606 preCalc->poly = NULL; 607 break; 608 case PM_SUBTRACTION_KERNEL_HERM: 609 preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size); 610 preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size); 611 preCalc->uCoords = NULL; 612 preCalc->vCoords = NULL; 613 preCalc->poly = NULL; 614 break; 615 case PM_SUBTRACTION_KERNEL_RINGS: 616 // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure 617 // we allocate these vectors here, but leave the kernel generation to the main function 618 preCalc->xKernel = NULL; 619 preCalc->yKernel = NULL; 620 preCalc->kernel = NULL; 621 preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords 622 preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords 623 preCalc->poly = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial 624 return preCalc; 625 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 626 preCalc->kernel = pmSubtractionKernelHERM_RADIAL(sigma, uOrder, size); 627 preCalc->xKernel = NULL; 628 preCalc->yKernel = NULL; 629 preCalc->uCoords = NULL; 630 preCalc->vCoords = NULL; 631 preCalc->poly = NULL; 632 return preCalc; 633 default: 634 psAbort("programming error: invalid type for PreCalc kernel"); 635 } 636 637 preCalc->kernel = psKernelAlloc(-size, size, -size, size); // 2D Kernel 638 639 // generate 2D kernel from 1D realizations 640 for (int v = -size, y = 0; v <= size; v++, y++) { 641 for (int u = -size, x = 0; u <= size; u++, x++) { 642 preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel 643 } 644 } 645 646 return preCalc; 647 } 648 649 pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder, float penalty, psRegion bounds, 245 650 pmSubtractionMode mode) 246 651 { … … 251 656 252 657 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(0, PM_SUBTRACTION_KERNEL_POIS, size, 253 spatialOrder, penalty, mode); // The kernels658 spatialOrder, penalty, bounds, mode); // Kernels 254 659 psStringAppend(&kernels->description, "POIS(%d,%d,%.2e)", size, spatialOrder, penalty); 255 660 psLogMsg("psModules.imcombine", PS_LOG_INFO, "POIS kernel: %d,%d --> %d elements", … … 266 671 pmSubtractionKernels *pmSubtractionKernelsISIS(int size, int spatialOrder, 267 672 const psVector *fwhms, const psVector *orders, 268 float penalty, p mSubtractionMode mode)673 float penalty, psRegion bounds, pmSubtractionMode mode) 269 674 { 270 675 pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder, fwhms, orders, 271 penalty, mode); // Kernels676 penalty, bounds, mode); // Kernels 272 677 if (!kernels) { 273 678 return NULL; … … 278 683 279 684 pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, int spatialOrder, int inner, int binning, 280 float penalty, p mSubtractionMode mode)685 float penalty, psRegion bounds, pmSubtractionMode mode) 281 686 { 282 687 PS_ASSERT_INT_POSITIVE(size, NULL); … … 299 704 300 705 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_SPAM, size, 301 spatialOrder, penalty, mode); // The kernels706 spatialOrder, penalty, bounds, mode); // Kernels 302 707 kernels->inner = inner; 303 708 psStringAppend(&kernels->description, "SPAM(%d,%d,%d,%d,%.2e)", size, inner, binning, spatialOrder, … … 370 775 371 776 pmSubtractionKernels *pmSubtractionKernelsFRIES(int size, int spatialOrder, int inner, float penalty, 372 p mSubtractionMode mode)777 psRegion bounds, pmSubtractionMode mode) 373 778 { 374 779 PS_ASSERT_INT_POSITIVE(size, NULL); … … 397 802 398 803 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_FRIES, size, 399 spatialOrder, penalty, mode); // The kernels804 spatialOrder, penalty, bounds, mode); // Kernels 400 805 kernels->inner = inner; 401 806 psStringAppend(&kernels->description, "FRIES(%d,%d,%d,%.2e)", size, inner, spatialOrder, penalty); … … 463 868 } 464 869 465 // Grid United with Normal Kernel 870 // Grid United with Normal Kernel [description: GUNK=ISIS(...)+POIS(...)] 466 871 pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *fwhms, 467 872 const psVector *orders, int inner, float penalty, 468 p mSubtractionMode mode)873 psRegion bounds, pmSubtractionMode mode) 469 874 { 470 875 PS_ASSERT_INT_POSITIVE(size, NULL); … … 479 884 480 885 pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder, fwhms, orders, 481 penalty, mode); // Kernels886 penalty, bounds, mode); // Kernels 482 887 kernels->type = PM_SUBTRACTION_KERNEL_GUNK; 483 888 psStringPrepend(&kernels->description, "GUNK="); … … 495 900 // RINGS --- just what it says 496 901 pmSubtractionKernels *pmSubtractionKernelsRINGS(int size, int spatialOrder, int inner, int ringsOrder, 497 float penalty, p mSubtractionMode mode)902 float penalty, psRegion bounds, pmSubtractionMode mode) 498 903 { 499 904 PS_ASSERT_INT_POSITIVE(size, NULL); … … 526 931 527 932 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_RINGS, size, 528 spatialOrder, penalty, mode); // The kernels933 spatialOrder, penalty, bounds, mode); // Kernels 529 934 kernels->inner = inner; 530 935 psStringAppend(&kernels->description, "RINGS(%d,%d,%d,%d,%.2e)", size, inner, ringsOrder, spatialOrder, … … 566 971 for (int vOrder = 0; vOrder <= (i == 0 ? 0 : ringsOrder - uOrder); vOrder++, index++) { 567 972 568 psArray *data = psArrayAlloc(3); // Container for data 569 psVector *uCoords = data->data[0] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_S32); // u coords 570 psVector *vCoords = data->data[1] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_S32); // v coords 571 psVector *poly = data->data[2] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_F32); // Polynomial 973 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0); 572 974 double moment = 0.0; // Moment, for penalty 573 975 574 976 if (i == 0) { 575 977 // Central pixel is easy 576 uCoords->data.S32[0] = vCoords->data.S32[0] = 0; 577 poly->data.F32[0] = 1.0; 578 uCoords->n = vCoords->n = poly->n = 1; 978 preCalc->uCoords->data.S32[0] = 0; 979 preCalc->vCoords->data.S32[0] = 0; 980 preCalc->poly->data.F32[0] = 1.0; 981 preCalc->uCoords->n = 1; 982 preCalc->vCoords->n = 1; 983 preCalc->poly->n = 1; 579 984 radiusLast = 0; 580 985 moment = 0.0; … … 594 999 float polyVal = uPoly * vPoly; // Value of polynomial 595 1000 if (polyVal != 0) { // No point adding it otherwise 596 uCoords->data.S32[j] = u;597 vCoords->data.S32[j] = v;598 p oly->data.F32[j] = polyVal;1001 preCalc->uCoords->data.S32[j] = u; 1002 preCalc->vCoords->data.S32[j] = v; 1003 preCalc->poly->data.F32[j] = polyVal; 599 1004 norm += polyVal; 600 moment += polyVal* PS_SQR(PS_SQR(u) + PS_SQR(v));601 602 psVectorExtend( uCoords, RINGS_BUFFER, 1);603 psVectorExtend( vCoords, RINGS_BUFFER, 1);604 psVectorExtend(p oly, RINGS_BUFFER, 1);1005 moment += PS_SQR(polyVal) * PS_SQR(PS_SQR(u) + PS_SQR(v)); 1006 1007 psVectorExtend(preCalc->uCoords, RINGS_BUFFER, 1); 1008 psVectorExtend(preCalc->vCoords, RINGS_BUFFER, 1); 1009 psVectorExtend(preCalc->poly, RINGS_BUFFER, 1); 605 1010 psTrace("psModules.imcombine", 9, "u = %d, v = %d, poly = %f\n", 606 u, v, p oly->data.F32[j]);1011 u, v, preCalc->poly->data.F32[j]); 607 1012 j++; 608 1013 } … … 612 1017 // Normalise kernel component to unit sum 613 1018 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 614 psBinaryOp(p oly,poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32));1019 psBinaryOp(preCalc->poly, preCalc->poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32)); 615 1020 // Add subtraction of 0,0 component to preserve photometric scaling 616 uCoords->data.S32[j] = 0;617 vCoords->data.S32[j] = 0;618 p oly->data.F32[j] = -1.0;619 psVectorExtend( uCoords, RINGS_BUFFER, 1);620 psVectorExtend( vCoords, RINGS_BUFFER, 1);621 psVectorExtend(p oly, RINGS_BUFFER, 1);1021 preCalc->uCoords->data.S32[j] = 0; 1022 preCalc->vCoords->data.S32[j] = 0; 1023 preCalc->poly->data.F32[j] = -1.0; 1024 psVectorExtend(preCalc->uCoords, RINGS_BUFFER, 1); 1025 psVectorExtend(preCalc->vCoords, RINGS_BUFFER, 1); 1026 psVectorExtend(preCalc->poly, RINGS_BUFFER, 1); 622 1027 } else { 623 1028 norm = powf(size, uOrder) * powf(size, vOrder); 624 psBinaryOp(p oly,poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32));1029 psBinaryOp(preCalc->poly, preCalc->poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32)); 625 1030 } 626 moment /= norm;1031 moment /= PS_SQR(norm); 627 1032 } 628 1033 629 psTrace("psModules.imcombine", 8, "%ld pixels in kernel\n", uCoords->n);630 631 kernels->preCalc->data[index] = data;1034 psTrace("psModules.imcombine", 8, "%ld pixels in kernel\n", preCalc->uCoords->n); 1035 1036 kernels->preCalc->data[index] = preCalc; 632 1037 kernels->u->data.S32[index] = uOrder; 633 1038 kernels->v->data.S32[index] = vOrder; 634 1039 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 1040 if (!isfinite(kernels->penalties->data.F32[index])) { 1041 psAbort ("invalid penalty"); 1042 } 635 1043 636 1044 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d\n", index, … … 645 1053 pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, int size, int spatialOrder, 646 1054 const psVector *fwhms, const psVector *orders, int inner, 647 int binning, int ringsOrder, float penalty, 1055 int binning, int ringsOrder, float penalty, psRegion bounds, 648 1056 pmSubtractionMode mode) 649 1057 { 650 1058 switch (type) { 651 1059 case PM_SUBTRACTION_KERNEL_POIS: 652 return pmSubtractionKernelsPOIS(size, spatialOrder, penalty, mode);1060 return pmSubtractionKernelsPOIS(size, spatialOrder, penalty, bounds, mode); 653 1061 case PM_SUBTRACTION_KERNEL_ISIS: 654 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode); 1062 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1063 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1064 return pmSubtractionKernelsISIS_RADIAL(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1065 case PM_SUBTRACTION_KERNEL_HERM: 1066 return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1067 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1068 return pmSubtractionKernelsDECONV_HERM(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 655 1069 case PM_SUBTRACTION_KERNEL_SPAM: 656 return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, mode);1070 return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, bounds, mode); 657 1071 case PM_SUBTRACTION_KERNEL_FRIES: 658 return pmSubtractionKernelsFRIES(size, spatialOrder, inner, penalty, mode);1072 return pmSubtractionKernelsFRIES(size, spatialOrder, inner, penalty, bounds, mode); 659 1073 case PM_SUBTRACTION_KERNEL_GUNK: 660 return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner, penalty, mode);1074 return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner, penalty, bounds, mode); 661 1075 case PM_SUBTRACTION_KERNEL_RINGS: 662 return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder, penalty, mode);1076 return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder, penalty, bounds, mode); 663 1077 default: 664 1078 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unknown kernel type: %x", type); … … 696 1110 697 1111 pmSubtractionKernels *pmSubtractionKernelsFromDescription(const char *description, int bgOrder, 698 p mSubtractionMode mode)1112 psRegion bounds, pmSubtractionMode mode) 699 1113 { 700 1114 PS_ASSERT_STRING_NON_EMPTY(description, NULL); … … 715 1129 float penalty = 0.0; // Penalty for wideness 716 1130 717 if (strncmp(description, "ISIS", 4) == 0) { 718 // XXX Support for GUNK 719 if (strstr(description, "+POIS")) { 720 type = PM_SUBTRACTION_KERNEL_GUNK; 721 psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description); 722 } else { 723 type = PM_SUBTRACTION_KERNEL_ISIS; 724 char *ptr = (char*)description + 5; // Eat "ISIS(" 725 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 726 727 // Count the number of Gaussians 728 int numGauss = 0; 729 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 730 numGauss++; 731 } 732 733 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 734 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 735 736 for (int i = 0; i < numGauss; i++) { 737 ptr++; // Eat the '(' 738 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 739 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 740 } 741 742 ptr++; // Eat ',' 743 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 744 penalty = parseStringFloat(ptr); 745 } 746 } else if (strncmp(description, "RINGS", 5) == 0) { 747 type = PM_SUBTRACTION_KERNEL_RINGS; 748 char *ptr = (char*)description + 6; 1131 // currently known descriptions: 1132 // ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), SPAM(...), 1133 // FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 1134 // the descriptive name is the set of characters before the ( 1135 1136 type = pmSubtractionKernelsTypeFromString (description); 1137 char *ptr = strchr(description, '(') + 1; 1138 psAssert (ptr, "description is missing kernel parameters"); 1139 1140 switch (type) { 1141 case PM_SUBTRACTION_KERNEL_ISIS: 1142 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1143 case PM_SUBTRACTION_KERNEL_HERM: 1144 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1145 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 1146 1147 // Count the number of Gaussians 1148 int numGauss = 0; 1149 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 1150 numGauss++; 1151 } 1152 1153 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 1154 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 1155 1156 for (int i = 0; i < numGauss; i++) { 1157 ptr++; // Eat the '(' 1158 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 1159 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 1160 } 1161 1162 ptr++; // Eat ',' 1163 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 1164 penalty = parseStringFloat(ptr); 1165 break; 1166 case PM_SUBTRACTION_KERNEL_RINGS: 749 1167 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 750 1168 PARSE_STRING_NUMBER(inner, ptr, ',', parseStringInt); … … 752 1170 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 753 1171 PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt); 754 } else { 755 psAbort("Deciphering kernels other than ISIS and RINGS is not currently supported."); 756 } 757 758 759 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, 760 inner, binning, ringsOrder, penalty, mode); 761 } 762 763 1172 break; 1173 default: 1174 psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported."); 1175 } 1176 1177 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, 1178 ringsOrder, penalty, bounds, mode); 1179 } 1180 1181 1182 // the input string can either be just the name or the description string. Currently known 1183 // descriptions: ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), 1184 // SPAM(...), FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 764 1185 pmSubtractionKernelsType pmSubtractionKernelsTypeFromString(const char *type) 765 1186 { 766 if (strcasecmp(type, "POIS") == 0) { 1187 // for a bare name (ISIS, HERM), use the full string length. 1188 // otherwise, use the length up to the first '(' 1189 int nameLength = strlen(type); 1190 char *ptr = strchr(type, '('); 1191 if (ptr) { 1192 nameLength = ptr - type; 1193 } 1194 1195 if (strncasecmp(type, "POIS", nameLength) == 0) { 767 1196 return PM_SUBTRACTION_KERNEL_POIS; 768 1197 } 769 if (str casecmp(type, "ISIS") == 0) {1198 if (strncasecmp(type, "ISIS", nameLength) == 0) { 770 1199 return PM_SUBTRACTION_KERNEL_ISIS; 771 1200 } 772 if (strcasecmp(type, "SPAM") == 0) { 1201 if (strncasecmp(type, "ISIS_RADIAL", nameLength) == 0) { 1202 return PM_SUBTRACTION_KERNEL_ISIS_RADIAL; 1203 } 1204 if (strncasecmp(type, "HERM", nameLength) == 0) { 1205 return PM_SUBTRACTION_KERNEL_HERM; 1206 } 1207 if (strncasecmp(type, "DECONV_HERM", nameLength) == 0) { 1208 return PM_SUBTRACTION_KERNEL_DECONV_HERM; 1209 } 1210 if (strncasecmp(type, "SPAM", nameLength) == 0) { 773 1211 return PM_SUBTRACTION_KERNEL_SPAM; 774 1212 } 775 if (str casecmp(type, "FRIES") == 0) {1213 if (strncasecmp(type, "FRIES", nameLength) == 0) { 776 1214 return PM_SUBTRACTION_KERNEL_FRIES; 777 1215 } 778 if (str casecmp(type, "GUNK") == 0) {1216 if (strncasecmp(type, "GUNK", nameLength) == 0) { 779 1217 return PM_SUBTRACTION_KERNEL_GUNK; 780 1218 } 781 if (strcasecmp(type, "RINGS") == 0) { 1219 // note that GUNK has a somewhat different description 1220 if (strncasecmp(type, "GUNK=ISIS", nameLength) == 0) { 1221 return PM_SUBTRACTION_KERNEL_GUNK; 1222 } 1223 if (strncasecmp(type, "RINGS", nameLength) == 0) { 782 1224 return PM_SUBTRACTION_KERNEL_RINGS; 783 1225 } … … 810 1252 out->bgOrder = in->bgOrder; 811 1253 out->mode = in->mode; 812 out->numCols = in->numCols; 813 out->numRows = in->numRows; 1254 out->xMin = in->xMin; 1255 out->xMax = in->xMax; 1256 out->yMin = in->yMin; 1257 out->yMax = in->yMax; 814 1258 out->solution1 = in->solution1 ? psVectorCopy(NULL, in->solution1, PS_TYPE_F64) : NULL; 815 1259 out->solution2 = in->solution2 ? psVectorCopy(NULL, in->solution2, PS_TYPE_F64) : NULL; 1260 out->sampleStamps = psMemIncrRefCounter(in->sampleStamps); 816 1261 817 1262 return out;
Note:
See TracChangeset
for help on using the changeset viewer.
