- Timestamp:
- May 3, 2010, 8:41:49 AM (16 years ago)
- Location:
- branches/tap_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/tap_branches
- Property svn:mergeinfo changed
-
branches/tap_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/tap_branches/psModules/src/imcombine/pmSubtractionKernels.c
r25120 r27838 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 … … 81 142 kernels->penalties = psVectorRealloc(kernels->penalties, start + numNew); 82 143 kernels->inner = start; 144 kernels->num += numNew; 83 145 84 146 // Generate a set of kernels for each (u,v) … … 94 156 kernels->v->data.S32[index] = v; 95 157 kernels->preCalc->data[index] = NULL; 96 kernels->penalties->data.F32[index] = kernels->penalty * (PS_SQR(u) + PS_SQR(v));97 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"); 98 160 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v); 99 161 } 100 162 } 101 163 164 kernels->widths->n = start + numNew; 165 kernels->u->n = start + numNew; 166 kernels->v->n = start + numNew; 167 kernels->preCalc->n = start + numNew; 168 kernels->penalties->n = start + numNew; 169 102 170 return true; 103 171 } 104 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 105 276 pmSubtractionKernels *p_pmSubtractionKernelsRawISIS(int size, int spatialOrder, 106 const psVector *fwhms , const psVector *orders,107 float penalty, p mSubtractionMode mode)108 { 109 PS_ASSERT_VECTOR_NON_NULL(fwhms , NULL);110 PS_ASSERT_VECTOR_TYPE(fwhms , PS_TYPE_F32, NULL);111 PS_ASSERT_VECTOR_NON_NULL(orders , NULL);112 PS_ASSERT_VECTOR_TYPE(orders , PS_TYPE_S32, NULL);113 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); 114 285 PS_ASSERT_INT_POSITIVE(size, NULL); 115 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 } 116 296 117 297 int numGaussians = fwhms->n; // Number of Gaussians … … 126 306 127 307 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS, size, 128 spatialOrder, penalty, mode); // The kernels308 spatialOrder, penalty, bounds, mode); // Kernels 129 309 psStringAppend(&kernels->description, "ISIS(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 130 310 … … 134 314 135 315 // Set the kernel parameters 136 int fullSize = 2 * size + 1; // Full size of kernels137 316 for (int i = 0, index = 0; i < numGaussians; i++) { 138 317 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma … … 140 319 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 141 320 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 142 psArray *preCalc = psArrayAlloc(2); // Array to hold precalculated values 143 psVector *xKernel = preCalc->data[0] = subtractionKernelISIS(sigma, uOrder, size); // x Kernel 144 psVector *yKernel = preCalc->data[1] = subtractionKernelISIS(sigma, vOrder, size); // y Kernel 145 146 // Calculate moments 147 double moment = 0.0; // Moment, for penalty 148 for (int v = -size, y = 0; v <= size; v++, y++) { 149 for (int u = -size, x = 0; u <= size; u++, x++) { 150 double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel 151 moment += value * (PS_SQR(u) + PS_SQR(v)); 152 } 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 psFree(orders); 330 psFree(fwhms); 331 332 return kernels; 333 } 334 335 pmSubtractionKernels *pmSubtractionKernelsISIS_RADIAL(int size, int spatialOrder, 336 const psVector *fwhmsIN, const psVector *ordersIN, 337 float penalty, psRegion bounds, pmSubtractionMode mode) 338 { 339 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 340 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 341 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 342 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 343 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 344 PS_ASSERT_INT_POSITIVE(size, NULL); 345 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 346 347 // check the requested fwhm values: any values <= 0.0 should be dropped 348 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 349 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 350 for (int i = 0; i < fwhmsIN->n; i++) { 351 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 352 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 353 psVectorAppend(orders, ordersIN->data.S32[i]); 354 } 355 356 int numGaussians = fwhms->n; // Number of Gaussians 357 358 int num = 0; // Number of basis functions 359 psString params = NULL; // List of parameters 360 for (int i = 0; i < numGaussians; i++) { 361 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 362 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 363 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 364 num += (11 - gaussOrder - 1); // include all higher order radial terms 365 } 366 367 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS_RADIAL, size, 368 spatialOrder, penalty, bounds, mode); // Kernels 369 psStringAppend(&kernels->description, "ISIS_RADIAL(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 370 371 psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS_RADIAL kernel: %s,%d --> %d elements", params, spatialOrder, num); 372 psFree(params); 373 374 // Set the kernel parameters 375 for (int i = 0, index = 0; i < numGaussians; i++) { 376 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 377 // Iterate over (u,v) order 378 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 379 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 380 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); 382 } 383 } 384 for (int order = orders->data.S32[i] + 1; order < 11; order ++, index ++) { 385 // XXX modify size for hermitians to account for sqrt(2) in Hermitian definition (relative to ISIS Gaussian) 386 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); 388 } 389 } 390 return kernels; 391 } 392 393 pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder, 394 const psVector *fwhmsIN, const psVector *ordersIN, 395 float penalty, psRegion bounds, pmSubtractionMode mode) 396 { 397 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 398 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 399 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 400 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 401 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 402 PS_ASSERT_INT_POSITIVE(size, NULL); 403 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 404 405 // check the requested fwhm values: any values <= 0.0 should be dropped 406 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 407 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 408 for (int i = 0; i < fwhmsIN->n; i++) { 409 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 410 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 411 psVectorAppend(orders, ordersIN->data.S32[i]); 412 } 413 414 int numGaussians = fwhms->n; // Number of Gaussians 415 416 int num = 0; // Number of basis functions 417 psString params = NULL; // List of parameters 418 for (int i = 0; i < numGaussians; i++) { 419 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 420 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 421 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 422 } 423 424 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_HERM, size, 425 spatialOrder, penalty, bounds, mode); // Kernels 426 psStringAppend(&kernels->description, "HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 427 428 psLogMsg("psModules.imcombine", PS_LOG_INFO, "HERM kernel: %s,%d --> %d elements", 429 params, spatialOrder, num); 430 psFree(params); 431 432 // Set the kernel parameters 433 for (int i = 0, index = 0; i < numGaussians; i++) { 434 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 435 // Iterate over (u,v) order 436 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 437 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 438 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); 440 } 441 } 442 } 443 444 return kernels; 445 } 446 447 pmSubtractionKernels *pmSubtractionKernelsDECONV_HERM(int size, int spatialOrder, 448 const psVector *fwhmsIN, const psVector *ordersIN, 449 float penalty, psRegion bounds, pmSubtractionMode mode) 450 { 451 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 452 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 453 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 454 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 455 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 456 PS_ASSERT_INT_POSITIVE(size, NULL); 457 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 458 459 // check the requested fwhm values: any values <= 0.0 should be dropped 460 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 461 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 462 for (int i = 0; i < fwhmsIN->n; i++) { 463 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 464 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 465 psVectorAppend(orders, ordersIN->data.S32[i]); 466 } 467 468 int numGaussians = fwhms->n; // Number of Gaussians 469 470 int num = 0; // Number of basis functions 471 psString params = NULL; // List of parameters 472 for (int i = 0; i < numGaussians; i++) { 473 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 474 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 475 num += PS_SQR(gaussOrder + 1); 476 } 477 478 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_DECONV_HERM, size, 479 spatialOrder, penalty, bounds, mode); // Kernels 480 psStringAppend(&kernels->description, "DECONV_HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 481 482 psLogMsg("psModules.imcombine", PS_LOG_INFO, "DECONVOLVED HERM kernel: %s,%d --> %d elements", params, spatialOrder, num); 483 psFree(params); 484 485 // XXXXX hard-wired reference sigma for now of 1.7 pix (== 4.0 pix fwhm == 1.0 arcsec in simtest) 486 // generate the Gaussian deconvolution kernel 487 # define DECONV_SIGMA 1.6 488 psKernel *kernelGauss = pmSubtractionDeconvolveGauss (size, DECONV_SIGMA); 489 490 # if 1 491 psArray *deconKernels = psArrayAllocEmpty(100); 492 # endif 493 494 // Set the kernel parameters 495 for (int i = 0, index = 0; i < numGaussians; i++) { 496 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 497 // Iterate over (u,v) order 498 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 499 for (int vOrder = 0; vOrder <= orders->data.S32[i]; vOrder++, index++) { 500 501 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values 502 503 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel 504 psKernel *kernelTarget = preCalc->kernel; 505 preCalc->kernel = pmSubtractionDeconvolveKernel(kernelTarget, kernelGauss); // Kernel 506 507 // 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); 509 510 // XXXX test demo that deconvolved kernel is valid 511 # if 1 512 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss); 513 psArrayAdd (deconKernels, 100, kernelConv); 514 psFree (kernelConv); 515 516 if (!uOrder && !vOrder){ 517 pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv); 153 518 } 154 155 // Normalise sum of kernel component to unity for even functions 156 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 157 double sum = 0.0; // Sum of kernel component 158 for (int v = 0; v < fullSize; v++) { 159 for (int u = 0; u < fullSize; u++) { 160 sum += xKernel->data.F32[u] * yKernel->data.F32[v]; 161 } 162 } 163 sum = 1.0 / sqrt(sum); 164 psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 165 psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 166 moment *= PS_SQR(sum); 519 # endif 520 } 521 } 522 } 523 524 # if 1 525 psImage *dot = psImageAlloc(deconKernels->n, deconKernels->n, PS_TYPE_F32); 526 for (int i = 0; i < deconKernels->n; i++) { 527 for (int j = 0; j <= i; j++) { 528 psImage *t1 = deconKernels->data[i]; 529 psImage *t2 = deconKernels->data[j]; 530 531 double sum = 0.0; 532 for (int iy = 0; iy < t1->numRows; iy++) { 533 for (int ix = 0; ix < t1->numCols; ix++) { 534 sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix]; 167 535 } 168 169 kernels->widths->data.F32[index] = fwhms->data.F32[i];170 kernels->u->data.S32[index] = uOrder;171 kernels->v->data.S32[index] = vOrder;172 if (kernels->preCalc->data[index]) {173 psFree(kernels->preCalc->data[index]);174 }175 kernels->preCalc->data[index] = preCalc;176 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);177 178 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index,179 fwhms->data.F32[i], uOrder, vOrder, fabsf(moment));180 536 } 181 } 182 } 537 dot->data.F32[j][i] = sum; 538 dot->data.F32[i][j] = sum; 539 } 540 } 541 pmSubtractionVisualShowSubtraction (dot, NULL, NULL); 542 psFree (dot); 543 psFree (deconKernels); 544 # endif 183 545 184 546 return kernels; … … 190 552 191 553 pmSubtractionKernels *pmSubtractionKernelsAlloc(int numBasisFunctions, pmSubtractionKernelsType type, 192 int size, int spatialOrder, float penalty, 554 int size, int spatialOrder, float penalty, psRegion bounds, 193 555 pmSubtractionMode mode) 194 556 { … … 202 564 kernels->v = psVectorAlloc(numBasisFunctions, PS_TYPE_S32); 203 565 kernels->widths = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 566 kernels->uStop = NULL; 567 kernels->vStop = NULL; 568 kernels->xMin = bounds.x0; 569 kernels->xMax = bounds.x1; 570 kernels->yMin = bounds.y0; 571 kernels->yMax = bounds.y1; 204 572 kernels->preCalc = psArrayAlloc(numBasisFunctions); 205 573 kernels->penalty = penalty; 206 574 kernels->penalties = psVectorAlloc(numBasisFunctions, PS_TYPE_F32); 207 kernels->uStop = NULL;208 kernels->vStop = NULL;209 575 kernels->size = size; 210 576 kernels->inner = 0; … … 212 578 kernels->bgOrder = 0; 213 579 kernels->mode = mode; 214 kernels->numCols = 0;215 kernels->numRows = 0;216 580 kernels->solution1 = NULL; 217 581 kernels->solution2 = NULL; 582 kernels->mean = NAN; 583 kernels->rms = NAN; 584 kernels->numStamps = 0; 585 kernels->sampleStamps = NULL; 586 587 kernels->fSigResMean = NAN; 588 kernels->fSigResStdev = NAN; 589 kernels->fMaxResMean = NAN; 590 kernels->fMaxResStdev = NAN; 591 kernels->fMinResMean = NAN; 592 kernels->fMinResStdev = NAN; 218 593 219 594 return kernels; 220 595 } 221 596 222 pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder, float penalty, 597 pmSubtractionKernelPreCalc *pmSubtractionKernelPreCalcAlloc(pmSubtractionKernelsType type, int uOrder, int vOrder, int size, float sigma) { 598 599 pmSubtractionKernelPreCalc *preCalc = psAlloc(sizeof(pmSubtractionKernelPreCalc)); // Kernels, to return 600 psMemSetDeallocator(preCalc, (psFreeFunc)pmSubtractionKernelPreCalcFree); 601 602 // 1D kernel realizations: 603 switch (type) { 604 case PM_SUBTRACTION_KERNEL_ISIS: 605 preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size); 606 preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size); 607 preCalc->uCoords = NULL; 608 preCalc->vCoords = NULL; 609 preCalc->poly = NULL; 610 break; 611 case PM_SUBTRACTION_KERNEL_HERM: 612 preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size); 613 preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size); 614 preCalc->uCoords = NULL; 615 preCalc->vCoords = NULL; 616 preCalc->poly = NULL; 617 break; 618 case PM_SUBTRACTION_KERNEL_RINGS: 619 // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure 620 // we allocate these vectors here, but leave the kernel generation to the main function 621 preCalc->xKernel = NULL; 622 preCalc->yKernel = NULL; 623 preCalc->kernel = NULL; 624 preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords 625 preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords 626 preCalc->poly = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial 627 return preCalc; 628 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 629 preCalc->kernel = pmSubtractionKernelHERM_RADIAL(sigma, uOrder, size); 630 preCalc->xKernel = NULL; 631 preCalc->yKernel = NULL; 632 preCalc->uCoords = NULL; 633 preCalc->vCoords = NULL; 634 preCalc->poly = NULL; 635 return preCalc; 636 default: 637 psAbort("programming error: invalid type for PreCalc kernel"); 638 } 639 640 preCalc->kernel = psKernelAlloc(-size, size, -size, size); // 2D Kernel 641 642 // generate 2D kernel from 1D realizations 643 for (int v = -size, y = 0; v <= size; v++, y++) { 644 for (int u = -size, x = 0; u <= size; u++, x++) { 645 preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel 646 } 647 } 648 649 return preCalc; 650 } 651 652 pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder, float penalty, psRegion bounds, 223 653 pmSubtractionMode mode) 224 654 { … … 228 658 int num = PS_SQR(2 * size + 1) - 1; // Number of basis functions 229 659 230 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc( num, PM_SUBTRACTION_KERNEL_POIS, size,231 spatialOrder, penalty, mode); // The kernels660 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(0, PM_SUBTRACTION_KERNEL_POIS, size, 661 spatialOrder, penalty, bounds, mode); // Kernels 232 662 psStringAppend(&kernels->description, "POIS(%d,%d,%.2e)", size, spatialOrder, penalty); 233 663 psLogMsg("psModules.imcombine", PS_LOG_INFO, "POIS kernel: %d,%d --> %d elements", … … 244 674 pmSubtractionKernels *pmSubtractionKernelsISIS(int size, int spatialOrder, 245 675 const psVector *fwhms, const psVector *orders, 246 float penalty, p mSubtractionMode mode)676 float penalty, psRegion bounds, pmSubtractionMode mode) 247 677 { 248 678 pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder, fwhms, orders, 249 penalty, mode); // Kernels679 penalty, bounds, mode); // Kernels 250 680 if (!kernels) { 251 681 return NULL; … … 256 686 257 687 pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, int spatialOrder, int inner, int binning, 258 float penalty, p mSubtractionMode mode)688 float penalty, psRegion bounds, pmSubtractionMode mode) 259 689 { 260 690 PS_ASSERT_INT_POSITIVE(size, NULL); … … 277 707 278 708 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_SPAM, size, 279 spatialOrder, penalty, mode); // The kernels709 spatialOrder, penalty, bounds, mode); // Kernels 280 710 kernels->inner = inner; 281 711 psStringAppend(&kernels->description, "SPAM(%d,%d,%d,%d,%.2e)", size, inner, binning, spatialOrder, … … 348 778 349 779 pmSubtractionKernels *pmSubtractionKernelsFRIES(int size, int spatialOrder, int inner, float penalty, 350 p mSubtractionMode mode)780 psRegion bounds, pmSubtractionMode mode) 351 781 { 352 782 PS_ASSERT_INT_POSITIVE(size, NULL); … … 375 805 376 806 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_FRIES, size, 377 spatialOrder, penalty, mode); // The kernels807 spatialOrder, penalty, bounds, mode); // Kernels 378 808 kernels->inner = inner; 379 809 psStringAppend(&kernels->description, "FRIES(%d,%d,%d,%.2e)", size, inner, spatialOrder, penalty); … … 441 871 } 442 872 443 // Grid United with Normal Kernel 873 // Grid United with Normal Kernel [description: GUNK=ISIS(...)+POIS(...)] 444 874 pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *fwhms, 445 875 const psVector *orders, int inner, float penalty, 446 p mSubtractionMode mode)876 psRegion bounds, pmSubtractionMode mode) 447 877 { 448 878 PS_ASSERT_INT_POSITIVE(size, NULL); … … 456 886 PS_ASSERT_INT_LESS_THAN(inner, size, NULL); 457 887 458 // XXX GUNK doesn't seem to work --- doesn't add the POIS components, or at least, they're not noticed459 460 888 pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder, fwhms, orders, 461 penalty, mode); // Kernels 889 penalty, bounds, mode); // Kernels 890 kernels->type = PM_SUBTRACTION_KERNEL_GUNK; 462 891 psStringPrepend(&kernels->description, "GUNK="); 463 892 psStringAppend(&kernels->description, "+POIS(%d,%d)", inner, spatialOrder); … … 474 903 // RINGS --- just what it says 475 904 pmSubtractionKernels *pmSubtractionKernelsRINGS(int size, int spatialOrder, int inner, int ringsOrder, 476 float penalty, p mSubtractionMode mode)905 float penalty, psRegion bounds, pmSubtractionMode mode) 477 906 { 478 907 PS_ASSERT_INT_POSITIVE(size, NULL); … … 505 934 506 935 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_RINGS, size, 507 spatialOrder, penalty, mode); // The kernels936 spatialOrder, penalty, bounds, mode); // Kernels 508 937 kernels->inner = inner; 509 938 psStringAppend(&kernels->description, "RINGS(%d,%d,%d,%d,%.2e)", size, inner, ringsOrder, spatialOrder, … … 545 974 for (int vOrder = 0; vOrder <= (i == 0 ? 0 : ringsOrder - uOrder); vOrder++, index++) { 546 975 547 psArray *data = psArrayAlloc(3); // Container for data 548 psVector *uCoords = data->data[0] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_S32); // u coords 549 psVector *vCoords = data->data[1] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_S32); // v coords 550 psVector *poly = data->data[2] = psVectorAllocEmpty(RINGS_BUFFER, PS_TYPE_F32); // Polynomial 976 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0); 551 977 double moment = 0.0; // Moment, for penalty 552 978 553 979 if (i == 0) { 554 980 // Central pixel is easy 555 uCoords->data.S32[0] = vCoords->data.S32[0] = 0; 556 poly->data.F32[0] = 1.0; 557 uCoords->n = vCoords->n = poly->n = 1; 981 preCalc->uCoords->data.S32[0] = 0; 982 preCalc->vCoords->data.S32[0] = 0; 983 preCalc->poly->data.F32[0] = 1.0; 984 preCalc->uCoords->n = 1; 985 preCalc->vCoords->n = 1; 986 preCalc->poly->n = 1; 558 987 radiusLast = 0; 559 988 moment = 0.0; … … 573 1002 float polyVal = uPoly * vPoly; // Value of polynomial 574 1003 if (polyVal != 0) { // No point adding it otherwise 575 uCoords->data.S32[j] = u;576 vCoords->data.S32[j] = v;577 p oly->data.F32[j] = polyVal;1004 preCalc->uCoords->data.S32[j] = u; 1005 preCalc->vCoords->data.S32[j] = v; 1006 preCalc->poly->data.F32[j] = polyVal; 578 1007 norm += polyVal; 579 moment += polyVal *(PS_SQR(u) + PS_SQR(v));580 581 psVectorExtend( uCoords, RINGS_BUFFER, 1);582 psVectorExtend( vCoords, RINGS_BUFFER, 1);583 psVectorExtend(p oly, RINGS_BUFFER, 1);1008 moment += PS_SQR(polyVal) * PS_SQR(PS_SQR(u) + PS_SQR(v)); 1009 1010 psVectorExtend(preCalc->uCoords, RINGS_BUFFER, 1); 1011 psVectorExtend(preCalc->vCoords, RINGS_BUFFER, 1); 1012 psVectorExtend(preCalc->poly, RINGS_BUFFER, 1); 584 1013 psTrace("psModules.imcombine", 9, "u = %d, v = %d, poly = %f\n", 585 u, v, p oly->data.F32[j]);1014 u, v, preCalc->poly->data.F32[j]); 586 1015 j++; 587 1016 } … … 591 1020 // Normalise kernel component to unit sum 592 1021 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 593 psBinaryOp(p oly,poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32));1022 psBinaryOp(preCalc->poly, preCalc->poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32)); 594 1023 // Add subtraction of 0,0 component to preserve photometric scaling 595 uCoords->data.S32[j] = 0;596 vCoords->data.S32[j] = 0;597 p oly->data.F32[j] = -1.0;598 psVectorExtend( uCoords, RINGS_BUFFER, 1);599 psVectorExtend( vCoords, RINGS_BUFFER, 1);600 psVectorExtend(p oly, RINGS_BUFFER, 1);1024 preCalc->uCoords->data.S32[j] = 0; 1025 preCalc->vCoords->data.S32[j] = 0; 1026 preCalc->poly->data.F32[j] = -1.0; 1027 psVectorExtend(preCalc->uCoords, RINGS_BUFFER, 1); 1028 psVectorExtend(preCalc->vCoords, RINGS_BUFFER, 1); 1029 psVectorExtend(preCalc->poly, RINGS_BUFFER, 1); 601 1030 } else { 602 1031 norm = powf(size, uOrder) * powf(size, vOrder); 603 psBinaryOp(p oly,poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32));1032 psBinaryOp(preCalc->poly, preCalc->poly, "*", psScalarAlloc(1.0 / norm, PS_TYPE_F32)); 604 1033 } 605 // moment /= norm;1034 moment /= PS_SQR(norm); 606 1035 } 607 1036 608 psTrace("psModules.imcombine", 8, "%ld pixels in kernel\n", uCoords->n);609 610 kernels->preCalc->data[index] = data;1037 psTrace("psModules.imcombine", 8, "%ld pixels in kernel\n", preCalc->uCoords->n); 1038 1039 kernels->preCalc->data[index] = preCalc; 611 1040 kernels->u->data.S32[index] = uOrder; 612 1041 kernels->v->data.S32[index] = vOrder; 613 1042 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 1043 if (!isfinite(kernels->penalties->data.F32[index])) { 1044 psAbort ("invalid penalty"); 1045 } 614 1046 615 1047 psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d\n", index, … … 624 1056 pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, int size, int spatialOrder, 625 1057 const psVector *fwhms, const psVector *orders, int inner, 626 int binning, int ringsOrder, float penalty, 1058 int binning, int ringsOrder, float penalty, psRegion bounds, 627 1059 pmSubtractionMode mode) 628 1060 { 629 1061 switch (type) { 630 1062 case PM_SUBTRACTION_KERNEL_POIS: 631 return pmSubtractionKernelsPOIS(size, spatialOrder, penalty, mode);1063 return pmSubtractionKernelsPOIS(size, spatialOrder, penalty, bounds, mode); 632 1064 case PM_SUBTRACTION_KERNEL_ISIS: 633 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode); 1065 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1066 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1067 return pmSubtractionKernelsISIS_RADIAL(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1068 case PM_SUBTRACTION_KERNEL_HERM: 1069 return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 1070 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1071 return pmSubtractionKernelsDECONV_HERM(size, spatialOrder, fwhms, orders, penalty, bounds, mode); 634 1072 case PM_SUBTRACTION_KERNEL_SPAM: 635 return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, mode);1073 return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, bounds, mode); 636 1074 case PM_SUBTRACTION_KERNEL_FRIES: 637 return pmSubtractionKernelsFRIES(size, spatialOrder, inner, penalty, mode);1075 return pmSubtractionKernelsFRIES(size, spatialOrder, inner, penalty, bounds, mode); 638 1076 case PM_SUBTRACTION_KERNEL_GUNK: 639 return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner, penalty, mode);1077 return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner, penalty, bounds, mode); 640 1078 case PM_SUBTRACTION_KERNEL_RINGS: 641 return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder, penalty, mode);1079 return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder, penalty, bounds, mode); 642 1080 default: 643 1081 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unknown kernel type: %x", type); … … 675 1113 676 1114 pmSubtractionKernels *pmSubtractionKernelsFromDescription(const char *description, int bgOrder, 677 p mSubtractionMode mode)1115 psRegion bounds, pmSubtractionMode mode) 678 1116 { 679 1117 PS_ASSERT_STRING_NON_EMPTY(description, NULL); … … 694 1132 float penalty = 0.0; // Penalty for wideness 695 1133 696 if (strncmp(description, "ISIS", 4) == 0) { 697 // XXX Support for GUNK 698 if (strstr(description, "+POIS")) { 699 type = PM_SUBTRACTION_KERNEL_GUNK; 700 psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description); 701 } else { 702 type = PM_SUBTRACTION_KERNEL_ISIS; 703 char *ptr = (char*)description + 5; // Eat "ISIS(" 704 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 705 706 // Count the number of Gaussians 707 int numGauss = 0; 708 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 709 numGauss++; 710 } 711 712 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 713 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 714 715 for (int i = 0; i < numGauss; i++) { 716 ptr++; // Eat the '(' 717 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 718 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 719 } 720 721 ptr++; // Eat ',' 722 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 723 penalty = parseStringFloat(ptr); 724 } 725 } else if (strncmp(description, "RINGS", 5) == 0) { 726 type = PM_SUBTRACTION_KERNEL_RINGS; 727 char *ptr = (char*)description + 6; 1134 // currently known descriptions: 1135 // ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), SPAM(...), 1136 // FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 1137 // the descriptive name is the set of characters before the ( 1138 1139 type = pmSubtractionKernelsTypeFromString (description); 1140 char *ptr = strchr(description, '(') + 1; 1141 psAssert (ptr, "description is missing kernel parameters"); 1142 1143 switch (type) { 1144 case PM_SUBTRACTION_KERNEL_ISIS: 1145 case PM_SUBTRACTION_KERNEL_ISIS_RADIAL: 1146 case PM_SUBTRACTION_KERNEL_HERM: 1147 case PM_SUBTRACTION_KERNEL_DECONV_HERM: 1148 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 1149 1150 // Count the number of Gaussians 1151 int numGauss = 0; 1152 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 1153 numGauss++; 1154 } 1155 1156 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 1157 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 1158 1159 for (int i = 0; i < numGauss; i++) { 1160 ptr++; // Eat the '(' 1161 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 1162 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 1163 } 1164 1165 ptr++; // Eat ',' 1166 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 1167 penalty = parseStringFloat(ptr); 1168 break; 1169 case PM_SUBTRACTION_KERNEL_RINGS: 728 1170 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 729 1171 PARSE_STRING_NUMBER(inner, ptr, ',', parseStringInt); … … 731 1173 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 732 1174 PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt); 733 } else { 734 psAbort("Deciphering kernels other than ISIS and RINGS is not currently supported."); 735 } 736 737 738 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, 739 inner, binning, ringsOrder, penalty, mode); 740 } 741 742 1175 break; 1176 default: 1177 psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported."); 1178 } 1179 1180 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, 1181 ringsOrder, penalty, bounds, mode); 1182 } 1183 1184 1185 // the input string can either be just the name or the description string. Currently known 1186 // descriptions: ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), 1187 // SPAM(...), FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...), 743 1188 pmSubtractionKernelsType pmSubtractionKernelsTypeFromString(const char *type) 744 1189 { 745 if (strcasecmp(type, "POIS") == 0) { 1190 // for a bare name (ISIS, HERM), use the full string length. 1191 // otherwise, use the length up to the first '(' 1192 int nameLength = strlen(type); 1193 char *ptr = strchr(type, '('); 1194 if (ptr) { 1195 nameLength = ptr - type; 1196 } 1197 1198 if (strncasecmp(type, "POIS", nameLength) == 0) { 746 1199 return PM_SUBTRACTION_KERNEL_POIS; 747 1200 } 748 if (str casecmp(type, "ISIS") == 0) {1201 if (strncasecmp(type, "ISIS", nameLength) == 0) { 749 1202 return PM_SUBTRACTION_KERNEL_ISIS; 750 1203 } 751 if (strcasecmp(type, "SPAM") == 0) { 1204 if (strncasecmp(type, "ISIS_RADIAL", nameLength) == 0) { 1205 return PM_SUBTRACTION_KERNEL_ISIS_RADIAL; 1206 } 1207 if (strncasecmp(type, "HERM", nameLength) == 0) { 1208 return PM_SUBTRACTION_KERNEL_HERM; 1209 } 1210 if (strncasecmp(type, "DECONV_HERM", nameLength) == 0) { 1211 return PM_SUBTRACTION_KERNEL_DECONV_HERM; 1212 } 1213 if (strncasecmp(type, "SPAM", nameLength) == 0) { 752 1214 return PM_SUBTRACTION_KERNEL_SPAM; 753 1215 } 754 if (str casecmp(type, "FRIES") == 0) {1216 if (strncasecmp(type, "FRIES", nameLength) == 0) { 755 1217 return PM_SUBTRACTION_KERNEL_FRIES; 756 1218 } 757 if (str casecmp(type, "GUNK") == 0) {1219 if (strncasecmp(type, "GUNK", nameLength) == 0) { 758 1220 return PM_SUBTRACTION_KERNEL_GUNK; 759 1221 } 760 if (strcasecmp(type, "RINGS") == 0) { 1222 // note that GUNK has a somewhat different description 1223 if (strncasecmp(type, "GUNK=ISIS", nameLength) == 0) { 1224 return PM_SUBTRACTION_KERNEL_GUNK; 1225 } 1226 if (strncasecmp(type, "RINGS", nameLength) == 0) { 761 1227 return PM_SUBTRACTION_KERNEL_RINGS; 762 1228 } … … 789 1255 out->bgOrder = in->bgOrder; 790 1256 out->mode = in->mode; 791 out->numCols = in->numCols; 792 out->numRows = in->numRows; 1257 out->xMin = in->xMin; 1258 out->xMax = in->xMax; 1259 out->yMin = in->yMin; 1260 out->yMax = in->yMax; 793 1261 out->solution1 = in->solution1 ? psVectorCopy(NULL, in->solution1, PS_TYPE_F64) : NULL; 794 1262 out->solution2 = in->solution2 ? psVectorCopy(NULL, in->solution2, PS_TYPE_F64) : NULL; 1263 out->sampleStamps = psMemIncrRefCounter(in->sampleStamps); 795 1264 796 1265 return out;
Note:
See TracChangeset
for help on using the changeset viewer.
