IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/ppStack/src

    • Property svn:ignore
      •  

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

    r25045 r27840  
    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             if (!readImage(&readout->image, options->imageNames->data[index], config) ||
    226                 !readImage(&readout->mask, options->maskNames->data[index], config) ||
    227                 !readImage(&readout->variance, options->varianceNames->data[index], config)) {
    228                 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.");
    229268                return false;
    230269            }
     
    232271            psRegion *region = psMetadataLookupPtr(NULL, conv->analysis,
    233272                                                   PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region
    234 
    235             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,
    236277                                  readout->image->numCols, readout->image->numRows);
    237278
    238279            psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel
     280            bool oldThreads = psImageCovarianceSetThreads(true);              // Old thread setting
    239281            psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix
     282            psImageCovarianceSetThreads(oldThreads);
    240283            psFree(readout->covariance);
    241284            readout->covariance = covar;
     
    256299            int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations
    257300            float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold
    258             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
    259307            const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type
    260308            pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type
     
    273321            float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor"
    274322
     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
    275335            // These values are specified specifically for stacking
    276336            const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename
     
    283343            pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF
    284344
     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
    285360            // For the sake of stamps, remove nearby sources
    286361            psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index],
    287362                                                       footprint); // Filtered list of sources
    288363
     364            bool oldThreads = pmReadoutFakeThreads(true); // Old threading state
    289365            if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows,
    290                                           stampSources, NULL, NULL, options->psf, NAN, footprint + size,
    291                                           false, true)) {
    292                 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.");
    293369                psFree(fake);
    294370                psFree(optWidths);
     
    296372                return false;
    297373            }
     374            pmReadoutFakeThreads(oldThreads);
    298375
    299376            fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK);
    300377
     378#if 1
    301379            // Add the background into the target image
    302380            psImage *bgImage = stackBackgroundModel(readout, config); // Image of background
    303381            psBinaryOp(fake->image, fake->image, "+", bgImage);
    304382            psFree(bgImage);
     383#endif
    305384
    306385#ifdef TESTING
     
    328407
    329408            if (threads > 0) {
    330                 pmSubtractionThreadsInit(readout, fake);
     409                pmSubtractionThreadsInit();
    331410            }
    332411
     
    335414                                                               PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel
    336415            if (kernel) {
    337                 if (!pmSubtractionMatchPrecalc(conv, NULL, readout, fake, readout->analysis,
    338                                                stride, sysError, maskVal, maskBad, maskPoor,
     416                if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis,
     417                                               stride, kernelError, covarFrac, maskVal, maskBad, maskPoor,
    339418                                               poorFrac, badFrac)) {
    340                     psError(PS_ERR_UNKNOWN, false, "Unable to convolve images.");
     419                    psError(psErrorCodeLast(), false, "Unable to convolve images.");
    341420                    psFree(fake);
    342421                    psFree(optWidths);
     
    344423                    psFree(conv);
    345424                    if (threads > 0) {
    346                         pmSubtractionThreadsFinalize(readout, fake);
     425                        pmSubtractionThreadsFinalize();
    347426                    }
    348427                    return false;
    349428                }
    350429            } else {
    351                 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing,
    352                                         threshold, stampSources, stampsName, type, size, order, widths,
    353                                         orders, inner, ringsOrder, binning, penalty,
    354                                         optimum, optWidths, optOrder, optThresh, iter, rej, sysError,
    355                                         maskVal, maskBad, maskPoor, poorFrac, badFrac,
    356                                         PM_SUBTRACTION_MODE_1)) {
    357                     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");
    358436                    psFree(fake);
    359437                    psFree(optWidths);
    360438                    psFree(stampSources);
    361439                    psFree(conv);
     440                    psFree(widthsCopy);
    362441                    if (threads > 0) {
    363                         pmSubtractionThreadsFinalize(readout, fake);
     442                        pmSubtractionThreadsFinalize();
    364443                    }
    365444                    return false;
    366445                }
    367             }
     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
    368467
    369468#ifdef TESTING
     
    396495
    397496            if (threads > 0) {
    398                 pmSubtractionThreadsFinalize(readout, fake);
     497                pmSubtractionThreadsFinalize();
    399498            }
    400499
     
    436535            while ((item = psMetadataGetAndIncrement(iter))) {
    437536                assert(item->type == PS_DATA_UNKNOWN);
    438                 // Set the normalisation dimensions, since these will be otherwise unavailable when reading
    439                 // the images by scans.
    440537                pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction
    441                 kernel->numCols = readout->image->numCols;
    442                 kernel->numRows = readout->image->numRows;
    443 
    444538                kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel);
    445539            }
     
    467561        }
    468562
     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
    469588        // Reject image completely if the maximum deconvolution fraction exceeds the limit
    470589        float deconv = psMetadataLookupF32(NULL, conv->analysis,
    471590                                           PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction
    472591        if (deconv > deconvLimit) {
    473             psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n",
    474                       deconv, deconvLimit);
     592            psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n",
     593                      deconv, deconvLimit, index);
    475594            psFree(conv);
    476595            return NULL;
     
    491610    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
    492611    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
    493       psWarning("Can't measure background for image.");
    494       psErrorClear();
     612        psWarning("Can't measure background for image.");
     613        psErrorClear();
    495614    } else {
    496       if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {
    497         psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)",
    498                  psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV));
    499         (void)psBinaryOp(readout->image, readout->image, "-",
    500                          psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32));
    501       }
    502     }
    503 
    504 
    505     // Measure the variance level for the weighting
    506     if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {
    507         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)) {
    508624        psFree(rng);
    509625        psFree(bg);
    510626        return false;
    511627    }
    512     options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *
    513                                                   psImageCovarianceFactor(readout->covariance));
    514     psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0,
    515                      "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]);
    516644
    517645    psFree(rng);
Note: See TracChangeset for help on using the changeset viewer.