Changeset 36075 for branches/eam_branches/ipp-20130711/psModules/src/imcombine/pmSubtractionSimple.c
- Timestamp:
- Aug 30, 2013, 4:55:55 PM (13 years ago)
- Location:
- branches/eam_branches/ipp-20130711
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20130711
- Property svn:mergeinfo changed
-
branches/eam_branches/ipp-20130711/psModules
- Property svn:mergeinfo changed
/trunk/psModules (added) merged: 35814,35817,35821,35867,35925,35938
- Property svn:mergeinfo changed
-
branches/eam_branches/ipp-20130711/psModules/src/imcombine/pmSubtractionSimple.c
r35784 r36075 63 63 } 64 64 65 bool simple_apply_mask(psImage *image, psImage *weight, psImage *mask, 66 psImageMaskType maskVal) { 67 for (int y = 0; y < mask->numRows; y++) { 68 for (int x = 0; x < mask->numCols; x++) { 69 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) { 70 image->data.F32[y][x] = NAN; 71 if (weight) { 72 weight->data.F32[y][x] = NAN; 73 } 74 } 75 } 76 } 77 return(true); 78 } 79 80 81 // Copied from pmSubtraction 82 static void solvedKernelPreCalc(psKernel *kernel, // Kernel, updated 83 const pmSubtractionKernels *kernels, // Kernel basis functions 84 float value, // Normalisation value for basis function 85 int index // Index of basis function of interest 86 ) 87 { 88 int size = kernels->size; // Kernel half-size 89 pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[index]; // Precalculated values 90 for (int v = -size; v <= size; v++) { 91 for (int u = -size; u <= size; u++) { 92 kernel->kernel[v][u] += value * preCalc->kernel->kernel[v][u]; 93 } 94 } 95 96 return; 97 } 98 //End copy 99 65 100 bool pmSubtractionSimpleMatch(pmReadout *conv1, 66 101 pmReadout *conv2, … … 71 106 psImageMaskType maskVal, 72 107 psImageMaskType maskBad, 73 psImageMaskType maskPoor 108 psImageMaskType maskPoor, 109 float deconvolveThreshold 74 110 ) { 75 111 // 76 112 // We've already validated the input values at this level 77 113 float sig2fwhm = 2.0 * sqrt(2.0 * log(2.0)); 78 float fwhm1 ,fwhm2;79 float sigma1 ,sigma2,sigmaKern;114 float fwhm1 = 0,fwhm2 = 0; 115 float sigma1 = 0,sigma2 = 0,sigmaKern = 0; 80 116 float chisq = 1.0; 81 117 int convolution_direction = 0; 82 psImage *image1; 83 psImage *mask1; 84 psImage *var1; 85 86 psImage *image2; 87 psImage *mask2; 88 psImage *var2; 89 90 psImage *imageC1; 91 psImage *maskC1; 92 psImage *varC1; 93 94 psImage *imageC2; 95 psImage *maskC2; 96 psImage *varC2; 97 118 psImage *image1 = NULL; 119 psImage *mask1 = NULL; 120 psImage *var1 = NULL; 121 122 psImage *image2 = NULL; 123 psImage *mask2 = NULL; 124 psImage *var2 = NULL; 125 126 psImage *imageC1 = NULL; 127 psImage *maskC1 = NULL; 128 psImage *varC1 = NULL; 129 130 psImage *imageC2 = NULL; 131 psImage *maskC2 = NULL; 132 psImage *varC2 = NULL; 133 134 psImage *maskTemp = NULL; 135 98 136 // Allocate images, as this is usually done by subtractionMatchAlloc after this function is called. 99 137 int numCols = ro1->image->numCols; … … 101 139 102 140 if (conv1) { 103 conv1->covariance = psMemIncrRefCounter(ro1->covariance);141 // conv1->covariance = psMemIncrRefCounter(ro1->covariance); 104 142 if (!conv1->image) { 105 143 conv1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); … … 118 156 } 119 157 if (conv2) { 120 conv2->covariance = psMemIncrRefCounter(ro2->covariance);158 // 121 159 if (!conv2->image) { 122 160 conv2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); … … 171 209 if (!conv1) { 172 210 if (convolution_direction == 1) { 173 chisq = 100; 174 } 175 convolution_direction = 2; 211 if (sigma1 - sigma2 > deconvolveThreshold) { 212 chisq = 100; 213 } 214 } 215 // convolution_direction = 2; 176 216 } 177 217 if (!conv2) { 178 218 if (convolution_direction == 2) { 179 chisq = 100; 180 } 181 convolution_direction = 1; 219 if (sigma2 - sigma1 > deconvolveThreshold) { 220 chisq = 100; 221 } 222 } 223 // convolution_direction = 1; 182 224 } 183 225 … … 186 228 int maskBox = (int) ceil(sigmaKern * 1.1774); // diameter is 1/2 FWHM 187 229 int maskBlank = 8; // I should be able to get this from a reference, right? 188 189 // 190 // Construct required kernel. No longer needed as we can direct convolve 191 // psVector *kernelVec = pmSubtractionKernelSIMPLE(sigmaKern,0,size); // This is normalized to unity. 192 // psFree(kernelVec); 193 194 // 195 // Do convolutions 196 if (convolution_direction == 1) { 197 psImageSmoothMask_Threaded(imageC1,image1,mask1,maskVal,sigmaKern,6,1e-6); 198 psImageSmoothMask_Threaded(varC1,var1,mask1,maskVal,sigmaKern * M_SQRT1_2,6,1e-6); 199 maskC1 = psImageConvolveMask(maskC1,mask1,maskVal,maskBad, 200 -maskBox,maskBox,-maskBox,maskBox); 201 if (conv2) { 202 imageC2 = psImageCopy(imageC2,image2,PS_TYPE_F32); 203 varC2 = psImageCopy(varC2,var2,PS_TYPE_F32); 204 maskC2 = psImageCopy(maskC2,mask2,PS_TYPE_IMAGE_MASK); 205 } 206 pmSubtractionBorder(imageC1,varC1,maskC1,maskBox,maskBlank); 207 pmSubtractionMaskApply(imageC1,varC1,maskC1,PM_SUBTRACTION_MODE_1); 208 } 209 else if (convolution_direction == 2) { 210 psImageSmoothMask_Threaded(imageC2,image2,mask2,maskVal,sigmaKern,6,1e-6); 211 psImageSmoothMask_Threaded(varC2,var2,mask2,maskVal,sigmaKern * M_SQRT1_2,6,1e-6); 212 maskC2 = psImageConvolveMask(maskC2,mask2,maskVal,maskBad, 213 -maskBox,maskBox,-maskBox,maskBox); 214 if (conv1) { 215 imageC1 = psImageCopy(imageC1,image1,PS_TYPE_F32); 216 varC1 = psImageCopy(varC1,var1,PS_TYPE_F32); 217 maskC1 = psImageCopy(maskC1,mask1,PS_TYPE_IMAGE_MASK); 218 } 219 pmSubtractionBorder(imageC2,varC2,maskC2,maskBox,maskBlank); 220 pmSubtractionMaskApply(imageC2,varC2,maskC2,PM_SUBTRACTION_MODE_2); 221 } 222 223 // 224 // Do normalization 225 float normalization = 1.0; 226 227 // Scan source list, do box photometry on peaks, and then solve the linear relation. 228 int photRadius = (int) floor(PS_MAX(sigma1,sigma2) * 2.0 * sqrt(2.0 * log(2.0))); // Go out a FWHM diameter from the center. 229 psVector *logFluxDifferences = psVectorAlloc(sources->n,PS_TYPE_F32); 230 psVector *fitMask = psVectorAlloc(sources->n,PS_TYPE_VECTOR_MASK); 231 for (int i = 0; i < sources->n; i++) { 232 pmSource *source = sources->data[i]; 233 int nPix1,nPix2; 234 float flux1,flux2; 235 236 if (convolution_direction == 1) { 237 simple_do_boxphot(&nPix1,&flux1,source,imageC1,maskC1,maskBad,photRadius); 238 if (conv2) { 239 simple_do_boxphot(&nPix2,&flux2,source,imageC2,maskC2,maskBad,photRadius); 240 } 241 else { 242 simple_do_boxphot(&nPix2,&flux2,source,image2,mask2,maskBad,photRadius); 243 } 244 } 245 else if (convolution_direction == 2) { 246 simple_do_boxphot(&nPix2,&flux2,source,imageC2,maskC2,maskBad,photRadius); 247 if (conv1) { 248 simple_do_boxphot(&nPix1,&flux1,source,imageC1,maskC1,maskBad,photRadius); 249 } 250 else { 251 simple_do_boxphot(&nPix1,&flux1,source,image1,mask1,maskBad,photRadius); 252 } 253 } 254 logFluxDifferences->data.F32[i] = flux2 - flux1; 255 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0; 256 if ((PS_MIN(nPix1,nPix2) <= 0.75 * PS_MAX(nPix1,nPix2))|| 257 (!isfinite(flux1))||(!isfinite(flux2))) { 258 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff; 259 } 260 261 // fprintf(stderr,"SOURCES: %d %g %g %g -> %d %d %g %g %d %g\n",i,source->peak->xf,source->peak->yf,source->psfMag, 262 // nPix1,nPix2,flux1,flux2,fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i],logFluxDifferences->data.F32[i]); 263 264 } 265 266 // Given the differences in log-flux space, the normalization factor is just the exponential of the median difference 267 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 268 if (!psVectorStats(stats,logFluxDifferences,NULL,fitMask,0xff)) { 269 // This should complain. 270 normalization = 1.0; 271 } 272 273 normalization = pow(10,stats->robustMedian); 274 // fprintf(stderr,"NORM: %g+/-%g\n",stats->robustMedian,stats->robustStdev); 275 276 psFree(stats); 277 psFree(logFluxDifferences); 278 psFree(fitMask); 279 280 // Apply normalization 281 if (normalization != 1.0) { 282 if ((conv1)&&((convolution_direction == 1))) { 283 psBinaryOp(imageC1,imageC1,"*",psScalarAlloc((float) normalization, PS_TYPE_F32)); 284 psBinaryOp(varC1,varC1,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32)); 285 } 286 else if ((conv2)&&(convolution_direction == 2)) { 287 normalization = 1.0 / normalization; // Because we fit one way, but are using it in the other. 288 psBinaryOp(imageC2,imageC2,"*",psScalarAlloc((float) normalization, PS_TYPE_F32)); 289 psBinaryOp(varC2,varC2,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32)); 290 } 291 } 292 293 230 int maskPoorVal = 16384; // Another value that should be found elsewhere. 294 231 // 295 232 // Make a fake pmSubtractionKernels element so we can add it appropriately. 296 // I call it fake because we've successfully done everything at this point297 // without having to define these things.233 // Defining everything here is a bit clunky, but it's necessary to get the covariance 234 // correct. 298 235 psVector *fwhms = psVectorAlloc(1,PS_TYPE_F32); 299 236 fwhms->data.F32[0] = sigmaKern * sig2fwhm; … … 329 266 kernels->numStamps = sources->n; 330 267 268 psKernel *kernel = psKernelAlloc(-size,size,-size,size); 269 solvedKernelPreCalc(kernel,kernels,1.0,0); 270 271 // 272 // Do convolutions 273 if (convolution_direction == 1) { 274 if (conv1) { 275 psImageSmoothMask_Threaded(imageC1,image1,mask1,maskVal,sigmaKern,6,1e-6); 276 psImageSmoothMask_Threaded(varC1,var1,mask1,maskVal,sigmaKern * M_SQRT1_2,6,1e-6); 277 278 maskTemp = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 279 maskTemp = psImageConvolveMask(maskTemp,mask1,maskVal,maskBad, // Mask bad values 280 -maskBox,maskBox,-maskBox,maskBox); 281 maskC1 = psImageConvolveMask(maskC1,maskTemp,maskPoorVal,maskPoor, // Mask poor values 282 -maskBox,maskBox,-maskBox,maskBox); 283 psFree(maskTemp); 284 285 conv1->covariance = psImageCovarianceCalculate(kernel,ro1->covariance); 286 pmSubtractionBorder(imageC1,varC1,maskC1,maskBox,maskBlank); 287 simple_apply_mask(imageC1,varC1,maskC1,maskBad); 288 } 289 if (conv2) { 290 imageC2 = psImageCopy(imageC2,image2,PS_TYPE_F32); 291 varC2 = psImageCopy(varC2,var2,PS_TYPE_F32); 292 maskC2 = psImageCopy(maskC2,mask2,PS_TYPE_IMAGE_MASK); 293 conv2->covariance = psMemIncrRefCounter(ro2->covariance); 294 } 295 } 296 else if (convolution_direction == 2) { 297 if (conv2) { 298 psImageSmoothMask_Threaded(imageC2,image2,mask2,maskVal,sigmaKern,6,1e-6); 299 psImageSmoothMask_Threaded(varC2,var2,mask2,maskVal,sigmaKern * M_SQRT1_2,6,1e-6); 300 301 maskTemp = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 302 maskTemp = psImageConvolveMask(maskTemp,mask2,maskVal,maskBad, // Mask bad values 303 -maskBox,maskBox,-maskBox,maskBox); 304 maskC2 = psImageConvolveMask(maskC2,maskTemp,maskPoorVal,maskPoor, // Mask poor values 305 -maskBox,maskBox,-maskBox,maskBox); 306 psFree(maskTemp); 307 308 conv2->covariance = psImageCovarianceCalculate(kernel,ro2->covariance); 309 pmSubtractionBorder(imageC2,varC2,maskC2,maskBox,maskBlank); 310 simple_apply_mask(imageC2,varC2,maskC2,maskBad); 311 } 312 if (conv1) { 313 imageC1 = psImageCopy(imageC1,image1,PS_TYPE_F32); 314 varC1 = psImageCopy(varC1,var1,PS_TYPE_F32); 315 maskC1 = psImageCopy(maskC1,mask1,PS_TYPE_IMAGE_MASK); 316 conv1->covariance = psMemIncrRefCounter(ro1->covariance); 317 } 318 } 319 320 psFree(kernel); // No longer needed after doing covariance calculation 321 322 // 323 // Do normalization 324 float normalization = 1.0; 325 326 // Scan source list, do box photometry on peaks, and then solve the linear relation. 327 int photRadius = (int) floor(PS_MAX(sigma1,sigma2) * 2.0 * sqrt(2.0 * log(2.0))); // Go out a FWHM diameter from the center. 328 psVector *logFluxDifferences = psVectorAlloc(sources->n,PS_TYPE_F32); 329 psVector *fitMask = psVectorAlloc(sources->n,PS_TYPE_VECTOR_MASK); 330 for (int i = 0; i < sources->n; i++) { 331 pmSource *source = sources->data[i]; 332 int nPix1,nPix2; 333 float flux1,flux2; 334 335 if (conv1) { 336 simple_do_boxphot(&nPix1,&flux1,source,imageC1,maskC1,maskBad,photRadius); 337 } 338 else { 339 simple_do_boxphot(&nPix1,&flux1,source,image1,mask1,maskBad,photRadius); 340 } 341 342 if (conv2) { 343 simple_do_boxphot(&nPix2,&flux2,source,imageC2,maskC2,maskBad,photRadius); 344 } 345 else { 346 simple_do_boxphot(&nPix2,&flux2,source,image2,mask2,maskBad,photRadius); 347 } 348 349 logFluxDifferences->data.F32[i] = flux2 - flux1; 350 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0; 351 if ((PS_MIN(nPix1,nPix2) <= 0.75 * PS_MAX(nPix1,nPix2))|| 352 (!isfinite(flux1))||(!isfinite(flux2))) { 353 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff; 354 } 355 356 // fprintf(stderr,"SOURCES: %d %g %g %g -> %d %d %g %g %d %g\n",i,source->peak->xf,source->peak->yf,source->psfMag, 357 // nPix1,nPix2,flux1,flux2,fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i],logFluxDifferences->data.F32[i]); 358 } 359 360 // Given the differences in log-flux space, the normalization factor is just the exponential of the median difference 361 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 362 if (!psVectorStats(stats,logFluxDifferences,NULL,fitMask,0xff)) { 363 // This should complain. 364 normalization = 1.0; 365 } 366 367 normalization = pow(10,stats->robustMedian); 368 // fprintf(stderr,"NORM: %g+/-%g\n",stats->robustMedian,stats->robustStdev); 369 370 psFree(stats); 371 psFree(logFluxDifferences); 372 psFree(fitMask); 373 374 // Apply normalization 375 if (normalization != 1.0) { 376 if ((conv1)&&((convolution_direction == 1))) { 377 psBinaryOp(imageC1,imageC1,"*",psScalarAlloc((float) normalization, PS_TYPE_F32)); 378 psBinaryOp(varC1,varC1,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32)); 379 } 380 else if ((conv2)&&(convolution_direction == 2)) { 381 normalization = 1.0 / normalization; // Because we fit one way, but are using it in the other. 382 psBinaryOp(imageC2,imageC2,"*",psScalarAlloc((float) normalization, PS_TYPE_F32)); 383 psBinaryOp(varC2,varC2,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32)); 384 } 385 } 386 387 388 // 389 331 390 // 332 391 // Actually add it to the headers
Note:
See TracChangeset
for help on using the changeset viewer.
