IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 30, 2013, 4:55:55 PM (13 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/eam_branches/ipp-20130711
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20130711

  • branches/eam_branches/ipp-20130711/psModules

  • branches/eam_branches/ipp-20130711/psModules/src/imcombine/pmSubtractionSimple.c

    r35784 r36075  
    6363
    6464
     65bool 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
     82static 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
    65100bool pmSubtractionSimpleMatch(pmReadout *conv1,
    66101                              pmReadout *conv2,
     
    71106                              psImageMaskType maskVal,
    72107                              psImageMaskType maskBad,
    73                               psImageMaskType maskPoor
     108                              psImageMaskType maskPoor,
     109                              float deconvolveThreshold
    74110                              ) {
    75111  //
    76112  // We've already validated the input values at this level
    77113  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;
    80116  float chisq = 1.0;
    81117  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 
    98136  // Allocate images, as this is usually done by subtractionMatchAlloc after this function is called. 
    99137  int numCols = ro1->image->numCols;
     
    101139
    102140  if (conv1) {
    103     conv1->covariance = psMemIncrRefCounter(ro1->covariance);
     141    //    conv1->covariance = psMemIncrRefCounter(ro1->covariance);
    104142    if (!conv1->image) {
    105143      conv1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     
    118156  }
    119157  if (conv2) {
    120     conv2->covariance = psMemIncrRefCounter(ro2->covariance);
     158    //   
    121159    if (!conv2->image) {
    122160      conv2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     
    171209  if (!conv1) {
    172210    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;
    176216  }
    177217  if (!conv2) {
    178218    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;
    182224  }
    183225 
     
    186228  int maskBox = (int) ceil(sigmaKern * 1.1774); // diameter is 1/2 FWHM
    187229  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.
    294231  //
    295232  // Make a fake pmSubtractionKernels element so we can add it appropriately.
    296   // I call it fake because we've successfully done everything at this point
    297   // without having to define these things.
     233  // Defining everything here is a bit clunky, but it's necessary to get the covariance
     234  // correct.
    298235  psVector *fwhms = psVectorAlloc(1,PS_TYPE_F32);
    299236  fwhms->data.F32[0] = sigmaKern * sig2fwhm;
     
    329266  kernels->numStamps = sources->n;
    330267 
     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 
    331390  //
    332391  // Actually add it to the headers
Note: See TracChangeset for help on using the changeset viewer.