IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 15, 2013, 4:51:40 PM (13 years ago)
Author:
watersc1
Message:

Fix covariance calculation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmSubtractionSimple.c

    r35817 r35821  
    6363
    6464
     65// Copied from pmSubtraction
     66static void solvedKernelPreCalc(psKernel *kernel, // Kernel, updated
     67                                const pmSubtractionKernels *kernels, // Kernel basis functions
     68                                float value,                         // Normalisation value for basis function
     69                                int index                  // Index of basis function of interest
     70                                )
     71{
     72  int size = kernels->size;           // Kernel half-size
     73  pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[index]; // Precalculated values
     74  for (int v = -size; v <= size; v++) {
     75    for (int u = -size; u <= size; u++) {
     76      kernel->kernel[v][u] +=  value * preCalc->kernel->kernel[v][u];
     77    }
     78  }
     79
     80  return;
     81}
     82//End copy
     83
    6584bool pmSubtractionSimpleMatch(pmReadout *conv1,
    6685                              pmReadout *conv2,
     
    101120
    102121  if (conv1) {
    103     conv1->covariance = psMemIncrRefCounter(ro1->covariance);
     122    //    conv1->covariance = psMemIncrRefCounter(ro1->covariance);
    104123    if (!conv1->image) {
    105124      conv1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     
    118137  }
    119138  if (conv2) {
    120     conv2->covariance = psMemIncrRefCounter(ro2->covariance);
     139    //   
    121140    if (!conv2->image) {
    122141      conv2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     
    188207
    189208  //
    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 
    294   //
    295209  // 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.
     210  // Defining everything here is a bit clunky, but it's necessary to get the covariance
     211  // correct.
    298212  psVector *fwhms = psVectorAlloc(1,PS_TYPE_F32);
    299213  fwhms->data.F32[0] = sigmaKern * sig2fwhm;
     
    329243  kernels->numStamps = sources->n;
    330244 
     245  psKernel *kernel = psKernelAlloc(-size,size,-size,size);
     246  solvedKernelPreCalc(kernel,kernels,1.0,0);
     247 
     248  //
     249  // Do convolutions
     250  if (convolution_direction == 1) {
     251    psImageSmoothMask_Threaded(imageC1,image1,mask1,maskVal,sigmaKern,6,1e-6);
     252    psImageSmoothMask_Threaded(varC1,var1,mask1,maskVal,sigmaKern * M_SQRT1_2,6,1e-6);
     253    maskC1 = psImageConvolveMask(maskC1,mask1,maskVal,maskBad,
     254                                 -maskBox,maskBox,-maskBox,maskBox);
     255    conv1->covariance = psImageCovarianceCalculate(kernel,ro1->covariance);
     256    if (conv2) {
     257      imageC2 = psImageCopy(imageC2,image2,PS_TYPE_F32);
     258      varC2   = psImageCopy(varC2,var2,PS_TYPE_F32);
     259      maskC2  = psImageCopy(maskC2,mask2,PS_TYPE_IMAGE_MASK);
     260      conv2->covariance = psMemIncrRefCounter(ro2->covariance);
     261    }
     262    pmSubtractionBorder(imageC1,varC1,maskC1,maskBox,maskBlank);
     263    pmSubtractionMaskApply(imageC1,varC1,maskC1,PM_SUBTRACTION_MODE_1);
     264  }
     265  else if (convolution_direction == 2) {
     266    psImageSmoothMask_Threaded(imageC2,image2,mask2,maskVal,sigmaKern,6,1e-6);
     267    psImageSmoothMask_Threaded(varC2,var2,mask2,maskVal,sigmaKern * M_SQRT1_2,6,1e-6);
     268    maskC2 = psImageConvolveMask(maskC2,mask2,maskVal,maskBad,
     269                                 -maskBox,maskBox,-maskBox,maskBox);
     270    conv2->covariance = psImageCovarianceCalculate(kernel,ro2->covariance);
     271    if (conv1) {
     272      imageC1 = psImageCopy(imageC1,image1,PS_TYPE_F32);
     273      varC1   = psImageCopy(varC1,var1,PS_TYPE_F32);
     274      maskC1  = psImageCopy(maskC1,mask1,PS_TYPE_IMAGE_MASK);
     275      conv1->covariance = psMemIncrRefCounter(ro1->covariance);
     276    }
     277    pmSubtractionBorder(imageC2,varC2,maskC2,maskBox,maskBlank);
     278    pmSubtractionMaskApply(imageC2,varC2,maskC2,PM_SUBTRACTION_MODE_2);
     279  }   
     280
     281  psFree(kernel); // No longer needed after doing covariance calculation
     282
     283  //
     284  // Do normalization
     285  float normalization = 1.0;
     286
     287  // Scan source list, do box photometry on peaks, and then solve the linear relation.
     288  int photRadius = (int) floor(PS_MAX(sigma1,sigma2) * 2.0 * sqrt(2.0 * log(2.0))); // Go out a FWHM diameter from the center.
     289  psVector *logFluxDifferences = psVectorAlloc(sources->n,PS_TYPE_F32);
     290  psVector *fitMask = psVectorAlloc(sources->n,PS_TYPE_VECTOR_MASK);
     291  for (int i = 0; i < sources->n; i++) {
     292    pmSource *source = sources->data[i];
     293    int nPix1,nPix2;
     294    float flux1,flux2;
     295
     296    if (convolution_direction == 1) {
     297      simple_do_boxphot(&nPix1,&flux1,source,imageC1,maskC1,maskBad,photRadius);
     298      if (conv2) {
     299        simple_do_boxphot(&nPix2,&flux2,source,imageC2,maskC2,maskBad,photRadius);
     300      }
     301      else {
     302        simple_do_boxphot(&nPix2,&flux2,source,image2,mask2,maskBad,photRadius);
     303      }
     304    }
     305    else if (convolution_direction == 2) {
     306      simple_do_boxphot(&nPix2,&flux2,source,imageC2,maskC2,maskBad,photRadius);
     307      if (conv1) {
     308        simple_do_boxphot(&nPix1,&flux1,source,imageC1,maskC1,maskBad,photRadius);
     309      }
     310      else {
     311        simple_do_boxphot(&nPix1,&flux1,source,image1,mask1,maskBad,photRadius);
     312      }
     313    }
     314    logFluxDifferences->data.F32[i] = flux2 - flux1;
     315    fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0;
     316    if ((PS_MIN(nPix1,nPix2) <= 0.75 * PS_MAX(nPix1,nPix2))||
     317        (!isfinite(flux1))||(!isfinite(flux2))) {
     318      fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff;
     319    }
     320
     321    //    fprintf(stderr,"SOURCES: %d %g %g %g -> %d %d %g %g %d %g\n",i,source->peak->xf,source->peak->yf,source->psfMag,
     322    //      nPix1,nPix2,flux1,flux2,fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i],logFluxDifferences->data.F32[i]);
     323   
     324  }
     325
     326  // Given the differences in log-flux space, the normalization factor is just the exponential of the median difference
     327  psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     328  if (!psVectorStats(stats,logFluxDifferences,NULL,fitMask,0xff)) {
     329    // This should complain.
     330    normalization = 1.0;
     331  }
     332
     333  normalization = pow(10,stats->robustMedian);
     334  // fprintf(stderr,"NORM: %g+/-%g\n",stats->robustMedian,stats->robustStdev);
     335 
     336  psFree(stats);
     337  psFree(logFluxDifferences);
     338  psFree(fitMask);
     339
     340  // Apply normalization
     341  if (normalization != 1.0) {
     342    if ((conv1)&&((convolution_direction == 1))) {
     343      psBinaryOp(imageC1,imageC1,"*",psScalarAlloc((float) normalization, PS_TYPE_F32));
     344      psBinaryOp(varC1,varC1,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32));
     345    }
     346    else if ((conv2)&&(convolution_direction == 2)) {
     347      normalization = 1.0 / normalization; // Because we fit one way, but are using it in the other.
     348      psBinaryOp(imageC2,imageC2,"*",psScalarAlloc((float) normalization, PS_TYPE_F32));
     349      psBinaryOp(varC2,varC2,"*",psScalarAlloc((float) PS_SQR(normalization), PS_TYPE_F32));
     350    }
     351  }
     352 
     353
     354  //
     355 
    331356  //
    332357  // Actually add it to the headers
Note: See TracChangeset for help on using the changeset viewer.