IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:45:22 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simmosaic_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simmosaic_branches

  • branches/simmosaic_branches/ppStack/src

    • Property svn:ignore
      •  

        old new  
        1010stamp-h1
        1111ppStackVersionDefinitions.h
         12ppStackErrorCodes.c
         13ppStackErrorCodes.h
  • branches/simmosaic_branches/ppStack/src/ppStackMatch.c

    r24846 r27839  
    1414#define FAKE_SIZE 1                     // Size of fake convolution kernel
    1515#define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | \
    16                      PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources
    17 #define FAINT_SOURCE_FRAC 1.0e-4         // Set minimum flux to this fraction of faintest source flux
     16                     PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to input sources
     17#define NOISE_FRACTION 0.01             // Set minimum flux to this fraction of noise
    1818#define COVAR_FRAC 0.01                 // Truncation fraction for covariance matrix
    1919
    20 //#define TESTING                         // Enable debugging output
     20// #define TESTING                         // Enable debugging output
    2121
    2222#ifdef TESTING
     
    3131    psFree(resolved);
    3232    if (!fits) {
    33         psError(PS_ERR_IO, false, "Unable to open previously produced image: %s", name);
     33        psError(PPSTACK_ERR_IO, false, "Unable to open previously produced image: %s", name);
    3434        return false;
    3535    }
    3636    psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest
    3737    if (!image) {
    38         psError(PS_ERR_IO, false, "Unable to read previously produced image: %s", name);
     38        psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image: %s", name);
    3939        psFitsClose(fits);
    4040        return false;
     
    8787    x->n = y->n = numGood;
    8888
    89     psTree *tree = psTreePlant(2, 2, x, y); // kd tree
     89    psTree *tree = psTreePlant(2, 2, PS_TREE_EUCLIDEAN, x, y); // kd tree
    9090
    9191    psArray *filtered = psArrayAllocEmpty(numGood); // Filtered list of sources
     
    115115    psFree(coords);
    116116    psFree(tree);
     117    psFree(x);
     118    psFree(y);
    117119
    118120    psLogMsg("ppStack", PS_LOG_INFO, "Filtered out %d of %d sources", numFiltered, numGood);
     
    144146    psMetadataAddU8(psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskBad);
    145147
    146     psImage *binned = psphotBackgroundModel(ro, config); // Binned background model
     148    psImage *binned = psphotModelBackgroundReadoutNoFile(ro, config); // Binned background model
    147149    psImageBinning *binning = psMetadataLookupPtr(NULL, ro->analysis,
    148150                                                  "PSPHOT.BACKGROUND.BINNING"); // Binning for model
     
    150152    psImage *unbinned = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Unbinned background model
    151153    if (!psImageUnbin(unbinned, binned, binning)) {
    152         psError(PS_ERR_UNKNOWN, false, "Unable to unbin background model");
     154        psError(PPSTACK_ERR_DATA, false, "Unable to unbin background model");
     155        psFree(binned);
    153156        psFree(unbinned);
    154157        return NULL;
    155158    }
    156 
    157     // XXX should these really be here?? (probably not...)
    158     // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL");
    159     // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV");
    160 
    161      return unbinned;
     159    psFree(binned);
     160
     161    return unbinned;
    162162}
     163
     164// Renormalise a readout's variance map
     165bool stackRenormaliseReadout(const pmConfig *config, // Configuration
     166                             pmReadout *readout      // Readout to renormalise
     167    )
     168{
     169#if 1
     170    bool mdok; // Status of metadata lookups
     171
     172    psMetadata *recipe = psMetadataLookupPtr(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppStack
     173    psAssert(recipe, "Need PPSTACK recipe");
     174
     175    if (!psMetadataLookupBool(&mdok, recipe, "RENORM")) return true;
     176
     177    int num = psMetadataLookupS32(&mdok, recipe, "RENORM.NUM");
     178    if (!mdok) {
     179        psError(PPSTACK_ERR_CONFIG, true, "RENORM.NUM is not set in the recipe");
     180        return false;
     181    }
     182    float minValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MIN");
     183    if (!mdok) {
     184        psError(PPSTACK_ERR_CONFIG, true, "RENORM.MIN is not set in the recipe");
     185        return false;
     186    }
     187    float maxValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MAX");
     188    if (!mdok) {
     189        psError(PPSTACK_ERR_CONFIG, true, "RENORM.MAX is not set in the recipe");
     190        return false;
     191    }
     192
     193    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask
     194
     195    psImageCovarianceTransfer(readout->variance, readout->covariance);
     196    return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid);
     197#else
     198    return true;
     199#endif
     200}
     201
    163202
    164203
     
    178217    int size = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
    179218
    180     psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in
     219    psString maskValStr = psMetadataLookupStr(NULL, ppsub, "MASK.VAL"); // Name of bits to mask going in
    181220    psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
    182221    psString maskPoorStr = psMetadataLookupStr(NULL, recipe, "MASK.POOR"); // Name of bits to mask for poor
     
    190229
    191230    if (!pmReadoutMaskNonfinite(readout, maskVal)) {
    192         psError(PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in readout.");
     231        psError(psErrorCodeLast(), false, "Unable to mask non-finite pixels in readout.");
    193232        return false;
    194233    }
     
    217256            psFree(resolved);
    218257            if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) {
    219                 psError(PS_ERR_IO, false, "Unable to read previously produced kernel");
     258                psError(PPSTACK_ERR_IO, false, "Unable to read previously produced kernel");
    220259                psFitsClose(fits);
    221260                return false;
     
    223262            psFitsClose(fits);
    224263
    225             // Add in variance factor
    226             pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis,
    227                                                                 PM_SUBTRACTION_ANALYSIS_KERNEL); // Kernels
    228             float vf = pmSubtractionVarianceFactor(kernels, 0.0, 0.0, false); // Variance factor
    229             psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR");
    230             if (!isfinite(vf)) {
    231                 vf = 1.0;
    232             }
    233             if (isfinite(vfItem->data.F32)) {
    234                 vfItem->data.F32 *= vf;
    235             } else {
    236                 vfItem->data.F32 = vf;
    237             }
    238 
    239             if (!readImage(&readout->image, options->imageNames->data[index], config) ||
    240                 !readImage(&readout->mask, options->maskNames->data[index], config) ||
    241                 !readImage(&readout->variance, options->varianceNames->data[index], config)) {
    242                 psError(PS_ERR_IO, false, "Unable to read previously produced image.");
     264            if (!readImage(&readout->image, options->convImages->data[index], config) ||
     265                !readImage(&readout->mask, options->convMasks->data[index], config) ||
     266                !readImage(&readout->variance, options->convVariances->data[index], config)) {
     267                psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image.");
    243268                return false;
    244269            }
     
    246271            psRegion *region = psMetadataLookupPtr(NULL, conv->analysis,
    247272                                                   PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region
    248 
    249             pmSubtractionAnalysis(readout->analysis, kernels, region,
     273            pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis,
     274                                                                PM_SUBTRACTION_ANALYSIS_KERNEL);
     275
     276            pmSubtractionAnalysis(conv->analysis, NULL, kernels, region,
    250277                                  readout->image->numCols, readout->image->numRows);
    251278
    252279            psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel
     280            bool oldThreads = psImageCovarianceSetThreads(true);              // Old thread setting
    253281            psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix
     282            psImageCovarianceSetThreads(oldThreads);
    254283            psFree(readout->covariance);
    255284            readout->covariance = covar;
     
    270299            int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations
    271300            float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold
    272             float sysError = psMetadataLookupF32(NULL, ppsub, "SYS"); // Relative systematic error in kernel
     301            float kernelError = psMetadataLookupF32(NULL, ppsub, "KERNEL.ERR"); // Relative systematic error in kernel
     302            float normFrac = psMetadataLookupF32(NULL, ppsub, "NORM.FRAC"); // Fraction of window for normalisn windw
     303            float sysError = psMetadataLookupF32(NULL, ppsub, "SYS.ERR"); // Relative systematic error in images
     304            float skyErr = psMetadataLookupF32(NULL, ppsub, "SKY.ERR"); // Additional error in sky
     305            float covarFrac = psMetadataLookupF32(NULL, ppsub, "COVAR.FRAC"); // Fraction for covariance calculation
     306
    273307            const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type
    274308            pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type
     
    287321            float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor"
    288322
     323            bool scale = psMetadataLookupBool(NULL, ppsub, "SCALE");        // Scale kernel parameters?
     324            float scaleRef = psMetadataLookupF32(NULL, ppsub, "SCALE.REF"); // Reference for scaling
     325            float scaleMin = psMetadataLookupF32(NULL, ppsub, "SCALE.MIN"); // Minimum for scaling
     326            float scaleMax = psMetadataLookupF32(NULL, ppsub, "SCALE.MAX"); // Maximum for scaling
     327            if (!isfinite(scaleRef) || !isfinite(scaleMin) || !isfinite(scaleMax)) {
     328                psError(PPSTACK_ERR_CONFIG, false,
     329                        "Scale parameters (SCALE.REF=%f, SCALE.MIN=%f, SCALE.MAX=%f) not set in PPSUB recipe.",
     330                        scaleRef, scaleMin, scaleMax);
     331                return false;
     332            }
     333
     334
    289335            // These values are specified specifically for stacking
    290336            const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename
     
    297343            pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF
    298344
     345            psStats *bg = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics for background
     346            psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
     347            if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
     348                psError(PPSTACK_ERR_DATA, false, "Can't measure background for image.");
     349                psFree(fake);
     350                psFree(optWidths);
     351                psFree(conv);
     352                psFree(bg);
     353                psFree(rng);
     354                return false;
     355            }
     356            float minFlux = NOISE_FRACTION * bg->robustStdev; // Minimum flux level for fake image
     357            psFree(rng);
     358            psFree(bg);
     359
    299360            // For the sake of stamps, remove nearby sources
    300361            psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index],
    301362                                                       footprint); // Filtered list of sources
    302363
     364            bool oldThreads = pmReadoutFakeThreads(true); // Old threading state
    303365            if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows,
    304                                           stampSources, NULL, NULL, options->psf, NAN, footprint + size,
    305                                           false, true)) {
    306                 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF.");
     366                                          stampSources, SOURCE_MASK, NULL, NULL, options->psf,
     367                                          minFlux, footprint + size, false, true)) {
     368                psError(PPSTACK_ERR_DATA, false, "Unable to generate fake image with target PSF.");
    307369                psFree(fake);
    308370                psFree(optWidths);
     
    310372                return false;
    311373            }
     374            pmReadoutFakeThreads(oldThreads);
    312375
    313376            fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK);
    314377
     378#if 1
    315379            // Add the background into the target image
    316380            psImage *bgImage = stackBackgroundModel(readout, config); // Image of background
    317381            psBinaryOp(fake->image, fake->image, "+", bgImage);
    318382            psFree(bgImage);
     383#endif
    319384
    320385#ifdef TESTING
     
    342407
    343408            if (threads > 0) {
    344                 pmSubtractionThreadsInit(readout, fake);
     409                pmSubtractionThreadsInit();
    345410            }
    346411
     
    349414                                                               PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel
    350415            if (kernel) {
    351                 if (!pmSubtractionMatchPrecalc(conv, NULL, readout, fake, readout->analysis,
    352                                                stride, sysError, maskVal, maskBad, maskPoor,
     416                if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis,
     417                                               stride, kernelError, covarFrac, maskVal, maskBad, maskPoor,
    353418                                               poorFrac, badFrac)) {
    354                     psError(PS_ERR_UNKNOWN, false, "Unable to convolve images.");
     419                    psError(psErrorCodeLast(), false, "Unable to convolve images.");
    355420                    psFree(fake);
    356421                    psFree(optWidths);
     
    358423                    psFree(conv);
    359424                    if (threads > 0) {
    360                         pmSubtractionThreadsFinalize(readout, fake);
     425                        pmSubtractionThreadsFinalize();
    361426                    }
    362427                    return false;
    363428                }
    364429            } else {
    365                 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing,
    366                                         threshold, stampSources, stampsName, type, size, order, widths,
    367                                         orders, inner, ringsOrder, binning, penalty,
    368                                         optimum, optWidths, optOrder, optThresh, iter, rej, sysError,
    369                                         maskVal, maskBad, maskPoor, poorFrac, badFrac,
    370                                         PM_SUBTRACTION_MODE_1)) {
    371                     psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
     430                // Scale the input parameters
     431                psVector *widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths
     432                if (scale && !pmSubtractionParamsScale(&size, &footprint, widthsCopy,
     433                                                       options->inputSeeing->data.F32[index],
     434                                                       options->targetSeeing, scaleRef, scaleMin, scaleMax)) {
     435                    psError(psErrorCodeLast(), false, "Unable to scale kernel parameters");
    372436                    psFree(fake);
    373437                    psFree(optWidths);
    374438                    psFree(stampSources);
    375439                    psFree(conv);
     440                    psFree(widthsCopy);
    376441                    if (threads > 0) {
    377                         pmSubtractionThreadsFinalize(readout, fake);
     442                        pmSubtractionThreadsFinalize();
    378443                    }
    379444                    return false;
    380445                }
    381             }
     446
     447                if (!pmSubtractionMatch(NULL, conv, fake, readout, footprint, stride, regionSize, spacing,
     448                                        threshold, stampSources, stampsName, type, size, order, widthsCopy,
     449                                        orders, inner, ringsOrder, binning, penalty,
     450                                        optimum, optWidths, optOrder, optThresh, iter, rej, normFrac,
     451                                        sysError, skyErr, kernelError, covarFrac, maskVal, maskBad, maskPoor,
     452                                        poorFrac, badFrac, PM_SUBTRACTION_MODE_2)) {
     453                    psError(psErrorCodeLast(), false, "Unable to match images.");
     454                    psFree(fake);
     455                    psFree(optWidths);
     456                    psFree(stampSources);
     457                    psFree(conv);
     458                    psFree(widthsCopy);
     459                    if (threads > 0) {
     460                        pmSubtractionThreadsFinalize();
     461                    }
     462                    return false;
     463                }
     464                psFree(widthsCopy);
     465            }
     466
    382467
    383468#ifdef TESTING
     
    410495
    411496            if (threads > 0) {
    412                 pmSubtractionThreadsFinalize(readout, fake);
    413             }
    414 
    415             // Set the variance factor
    416             psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR");
    417             float vf = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1);
    418             if (!isfinite(vf)) {
    419                 vf = 1.0;
    420             }
    421             if (isfinite(vfItem->data.F32)) {
    422                 vfItem->data.F32 *= vf;
    423             } else {
    424                 vfItem->data.F32 = vf;
     497                pmSubtractionThreadsFinalize();
    425498            }
    426499
     
    462535            while ((item = psMetadataGetAndIncrement(iter))) {
    463536                assert(item->type == PS_DATA_UNKNOWN);
    464                 // Set the normalisation dimensions, since these will be otherwise unavailable when reading
    465                 // the images by scans.
    466537                pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction
    467                 kernel->numCols = readout->image->numCols;
    468                 kernel->numRows = readout->image->numRows;
    469 
    470538                kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel);
    471539            }
     
    493561        }
    494562
     563        // Kernel normalisation
     564        {
     565            double sum = 0.0;           // Sum of chi^2
     566            int num = 0;                // Number of measurements of chi^2
     567            psString regex = NULL;      // Regular expression
     568            psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM);
     569            psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex);
     570            psFree(regex);
     571            psMetadataItem *item = NULL;// Item from iteration
     572            while ((item = psMetadataGetAndIncrement(iter))) {
     573                assert(item->type == PS_TYPE_F32);
     574                float norm = item->data.F32; // Normalisation
     575                sum += norm;
     576                num++;
     577            }
     578            psFree(iter);
     579            float conv = sum/num;       // Mean normalisation from convolution
     580            float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars
     581            float renorm =  stars / conv; // Renormalisation to apply
     582            psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n",
     583                     index, renorm, conv, stars);
     584            psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32));
     585            psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32));
     586        }
     587
    495588        // Reject image completely if the maximum deconvolution fraction exceeds the limit
    496589        float deconv = psMetadataLookupF32(NULL, conv->analysis,
    497590                                           PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction
    498591        if (deconv > deconvLimit) {
    499             psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n",
    500                       deconv, deconvLimit);
     592            psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n",
     593                      deconv, deconvLimit, index);
    501594            psFree(conv);
    502595            return NULL;
     
    512605        psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(norm), PS_TYPE_F32));
    513606    }
    514    
     607
    515608    // Ensure the background value is zero
    516609    psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background
    517610    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
    518611    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
    519       psWarning("Can't measure background for image.");
    520       psErrorClear();
     612        psWarning("Can't measure background for image.");
     613        psErrorClear();
    521614    } else {
    522       if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {
    523         psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)",
    524                  psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV));
    525         (void)psBinaryOp(readout->image, readout->image, "-",
    526                          psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32));
    527       }
    528     }
    529    
    530 
    531     // Measure the variance level for the weighting
    532     if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {
    533         psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image.");
     615        if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {
     616            psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)",
     617                     psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV));
     618            (void)psBinaryOp(readout->image, readout->image, "-",
     619                             psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32));
     620        }
     621    }
     622
     623    if (!stackRenormaliseReadout(config, readout)) {
    534624        psFree(rng);
    535625        psFree(bg);
    536626        return false;
    537627    }
    538     options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *
    539                                                   psImageCovarianceFactor(readout->covariance));
    540     psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0,
    541                      "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]);
     628
     629    // Measure the variance level for the weighting
     630    if (psMetadataLookupBool(NULL, recipe, "WEIGHTS")) {
     631        if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {
     632            psError(PPSTACK_ERR_DATA, false, "Can't measure mean variance for image.");
     633            psFree(rng);
     634            psFree(bg);
     635            return false;
     636        }
     637        options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *
     638                                                      psImageCovarianceFactor(readout->covariance));
     639    } else {
     640        options->weightings->data.F32[index] = 1.0;
     641    }
     642    psLogMsg("ppStack", PS_LOG_INFO, "Weighting for image %d is %f\n",
     643             index, options->weightings->data.F32[index]);
    542644
    543645    psFree(rng);
Note: See TracChangeset for help on using the changeset viewer.