IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 19, 2012, 5:24:19 PM (14 years ago)
Author:
mhuber
Message:

merging latest r34040 trunk changes to branch

Location:
branches/meh_branches/ppstack_test
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/meh_branches/ppstack_test

  • branches/meh_branches/ppstack_test/psphot

  • branches/meh_branches/ppstack_test/psphot/src

  • branches/meh_branches/ppstack_test/psphot/src/psphotKronIterate.c

    r33415 r34041  
    11# include "psphotInternal.h"
    2 # ifndef ROUND
    3 # define ROUND(X) ((int) ((X) + 0.5*SIGN(X)))
    4 # endif
    5 
    6 bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert);
    7 bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal);
     2
     3bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert, bool oldWindow);
     4bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal, bool applyWeight, psImage *smoothedPixels);
     5
    86
    97bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule)
     
    119    bool status = true;
    1210
    13     // return true;
    14 
    1511    fprintf (stdout, "\n");
    1612    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Kron Iterate ---");
     
    4642        // psAssert (psf, "missing psf?");
    4743
    48         if (!psphotKronIterateReadout (config, recipe, view, readout, sources, psf)) {
     44        if (!psphotKronIterateReadout (config, recipe, view, filerule, readout, sources, psf, i)) {
    4945            psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for %s entry %d", filerule, i);
    5046            return false;
     
    5854bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max);
    5955
    60 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf) {
     56bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index) {
    6157
    6258    bool status = false;
     
    6965    psTimerStart ("psphot.kron");
    7066
     67
    7168    // determine the number of allowed threads
    7269    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     
    8481        MIN_KRON_RADIUS = 0.25*RADIUS;
    8582    }
     83
     84    int KRON_ITERATIONS = psMetadataLookupS32 (&status, recipe, "KRON_ITERATIONS");
     85    if (!status) {
     86        KRON_ITERATIONS = 1;
     87    }
     88
     89    bool KRON_APPLY_WEIGHT = psMetadataLookupBool (&status, recipe, "KRON_APPLY_WEIGHT");
     90    if (!status) {
     91        KRON_APPLY_WEIGHT = true;
     92    }
     93
     94    bool KRON_APPLY_WINDOW = psMetadataLookupBool (&status, recipe, "KRON_APPLY_WINDOW");
     95    if (!status) {
     96        KRON_APPLY_WINDOW = false;
     97    }
     98    bool KRON_SMOOTH = psMetadataLookupBool (&status, recipe, "KRON_SMOOTH");
     99    if (!status) {
     100        KRON_SMOOTH = false;
     101    }
     102    float KRON_SMOOTH_SIGMA = psMetadataLookupF32 (&status, recipe, "KRON_SMOOTH_SIGMA");
     103    if (!status) {
     104        KRON_SMOOTH_SIGMA = 1.7;
     105    }
     106    float KRON_SMOOTH_NSIGMA = psMetadataLookupS32 (&status, recipe, "KRON_SMOOTH_NSIGMA");
     107    if (!status) {
     108        KRON_SMOOTH_NSIGMA = 2;
     109    }
     110    /*
     111     *  Parameter for calculating maximum integration radius based on source's surface
     112     *  brightness
     113     *  Given minimum surface brightness SBmin and a flux the maximum radius is found from
     114     *
     115     *  SBmin = source->flux / (pi * Rmax**2)
     116     *  Rmax = sqrt (source->flux ) / sqrt (SBmin * pi)
     117     *
     118     *  Now what do we use for SBmin?
     119     *
     120     *  SBmin = ( some flux ) / (some area)
     121     *  some flux ~ flux of Ns sigma PSF source
     122     *  some area ~ K times area of a PSF
     123     * 
     124     * flux of Ns sigma source ~ Ns * SKY_STDEV * PSF_EFFECTIVE_AREA
     125     * PSF_EFFECTIVE_AREA = 4 pi sigma_PSF^2
     126     * (the 4 accounts for the fact that 1 sigma is not the total area, it is
     127     * actually a larger region).
     128     *
     129     *   SBmin = Ns * SKY_STDEV * 4 * pi * sigma_PSF^2 / (K * pi * sigma_PSF^2)
     130     *         = Ns * SKY_STDEV * 4 / K
     131     *
     132     * We combine the two parameters Ns and K, and the constant 4 into a single recipe value
     133     * KRON_SB_MIN_FACTOR with Ns = 5 and K = 2 the corresponding value
     134     * for KRON_SB_MIN_FACTOR is 5 * 4 / 2 = 10
     135     */
     136    float KRON_SB_MIN_FACTOR = psMetadataLookupF32 (&status, recipe, "KRON_SB_MIN_FACTOR");
     137    if (!status) {
     138        KRON_SB_MIN_FACTOR = 10;
     139    }
     140    float SKY_STDEV = psMetadataLookupF32 (&status, readout->analysis, "MSKY_DEV");
     141    float KRON_SB_MIN_DIVISOR = sqrt ( M_PI * KRON_SB_MIN_FACTOR * SKY_STDEV );
    86142
    87143    // bit-masks to test for good/bad pixels
     
    114170        // set a window function for each source based on the moments
    115171        // (this skips really bad sources (no peak, no moments, DEFECT)
    116         psphotKronWindowSetSource (source, kronWindow, false, true);
     172        psphotKronWindowSetSource (source, kronWindow, false, true, KRON_APPLY_WINDOW);
     173    }
     174
     175    // We measure the Kron Radius on a smoothed copy of the readout image
     176    psImage *smoothedImage = NULL;
     177    if (KRON_SMOOTH) {
     178        // Build the smoothed source image
     179        // Replace the subtracted sources
     180        psphotReplaceAllSourcesReadout(config, view, filerule, index, recipe, false);
     181        // Copy the image and smooth
     182        psTimerStart ("psphot.kron.smooth");
     183        smoothedImage = psImageCopy(NULL, readout->image, PS_TYPE_F32);
     184        psImageSmooth(smoothedImage, KRON_SMOOTH_SIGMA, KRON_SMOOTH_NSIGMA);
     185        psLogMsg ("psphot.kron", PS_LOG_INFO, "smoothed image %f sec\n", psTimerMark ("psphot.kron.smooth"));
     186
     187        // remove the sources
     188        psphotRemoveAllSourcesReadout( config, view, filerule, index, recipe, false );
     189        // Now subtract smooth versions of the sources from the smoothed image
     190        psTimerStart ("psphot.kron.smooth.sources");
     191        for (int i=0; i< sources->n; i++) {
     192            pmSource *source = sources->data[i];
     193            // If source has been subtracted from the readout image subtract a "smoothed" version from the smoothedImage
     194            if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
     195                // cache copy of smoothedPixels in the source
     196                // tmpPtr is for use by a single "module" and must be null otherwise
     197                psAssert(source->tmpPtr == NULL, "source->tmpPtr is not null!");
     198
     199                psImage *smoothedPixels = psImageSubset(smoothedImage, source->region);
     200                source->tmpPtr = (psPtr) smoothedPixels;
     201                pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, false, maskVal, 0, 0);
     202            }
     203        }
     204        psLogMsg ("psphot.kron", PS_LOG_INFO, "removed %ld smoothed sources %f sec\n", sources->n, psTimerMark ("psphot.kron.smooth.sources"));
     205
    117206    }
    118207
     
    136225            psArrayAdd(job->args, 1, kronWindow);
    137226            psArrayAdd(job->args, 1, cells->data[j]); // sources
     227            psArrayAdd(job->args, 1, smoothedImage);
    138228            PS_ARRAY_ADD_SCALAR(job->args, markVal,            PS_TYPE_IMAGE_MASK);
    139229            PS_ARRAY_ADD_SCALAR(job->args, maskVal,            PS_TYPE_IMAGE_MASK);
    140230            PS_ARRAY_ADD_SCALAR(job->args, RADIUS,             PS_TYPE_F32);
    141231            PS_ARRAY_ADD_SCALAR(job->args, MIN_KRON_RADIUS,    PS_TYPE_F32);
     232            PS_ARRAY_ADD_SCALAR(job->args, KRON_ITERATIONS,    PS_TYPE_S32);
     233            PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WEIGHT, PS_TYPE_S32);
     234            PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WINDOW, PS_TYPE_S32);
     235            PS_ARRAY_ADD_SCALAR(job->args, KRON_SMOOTH_SIGMA,  PS_TYPE_F32);
     236            PS_ARRAY_ADD_SCALAR(job->args, KRON_SB_MIN_DIVISOR,PS_TYPE_F32);
    142237
    143238// set this to 0 to run without threading
     
    150245            if (!psphotKronIterate_Threaded(job)) {
    151246                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    152                 psFree(AnalysisRegion);
     247                // psFree(AnalysisRegion);
    153248                return false;
    154249            }
     
    174269    psFree (cellGroups);
    175270    psFree (kronWindow);
     271    if (KRON_SMOOTH) {
     272        for (int i = 0; i < sources->n; i++) {
     273            pmSource *source = sources->data[i];
     274            psFree(source->tmpPtr);
     275            source->tmpPtr = NULL;
     276        }
     277    }
     278    psFree (smoothedImage);
    176279
    177280    psLogMsg ("psphot.kron", PS_LOG_WARN, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n);
     
    184287    psImage *kronWindow             = job->args->data[1];
    185288    psArray *sources                = job->args->data[2];
    186     psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA);
    187     psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
    188     float RADIUS                    = PS_SCALAR_VALUE(job->args->data[5],F32);
    189     float MIN_KRON_RADIUS           = PS_SCALAR_VALUE(job->args->data[6],F32);
    190 
    191     // XXX TEST : set iteration to 1
    192     for (int j = 0; j < 1; j++) {
     289    psImage *smoothedImage          = job->args->data[3];
     290    psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
     291    psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
     292    float RADIUS                    = PS_SCALAR_VALUE(job->args->data[6],F32);
     293    float MIN_KRON_RADIUS           = PS_SCALAR_VALUE(job->args->data[7],F32);
     294    int KRON_ITERATIONS             = PS_SCALAR_VALUE(job->args->data[8],S32);
     295    bool KRON_APPLY_WEIGHT          = PS_SCALAR_VALUE(job->args->data[9],S32);
     296    bool KRON_APPLY_WINDOW          = PS_SCALAR_VALUE(job->args->data[10],S32);
     297    float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[11],F32);
     298    float KRON_SB_MIN_DIVISOR       = PS_SCALAR_VALUE(job->args->data[12],F32);
     299
     300    for (int j = 0; j < KRON_ITERATIONS; j++) {
    193301        for (int i = 0; i < sources->n; i++) {
    194302
     
    196304            if (!source->peak) continue; // XXX how can we have a peak-less source?
    197305
    198             // allocate space for moments
     306            // check status of this source's moments
    199307            if (!source->moments) continue;
     308            if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) continue;
     309            if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
    200310
    201311            // replace object in image
    202312            bool reSubtract = false;
     313            psImage *smoothedPixels = NULL;
    203314            if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
    204                 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     315                pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     316                smoothedPixels = (psImage *) source->tmpPtr;
     317                if (smoothedPixels) {
     318                    pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, true, maskVal, 0, 0);
     319                }
    205320                reSubtract = true;
    206321            }
    207322
    208             // use S/N to control max window size
    209             // float kronSN = source->moments->KronFlux / source->moments->KronFluxErr;
    210 
    211             // maxWindow -> 1.5*RADIUS for kronSN = 5.0, keeping S.B. constant (kronSN ~ flux)
    212             // (kronSN / maxWindow^2) = (5.0 / (1.5 RADIUS)^2)
    213             // maxWindow = 1.5 * RADIUS * sqrt(kronSN / 5.0)
    214             // XXX float maxWindow = (isfinite(kronSN) && (kronSN > 5.0)) ? 1.5 * RADIUS * sqrt(kronSN / 5.0) : 1.5*RADIUS;
    215 
    216             // iterate to the window radius
    217             // XXX float windowRadius = PS_MIN(PS_MAX(RADIUS, 4.0*source->moments->Mrf), maxWindow);
    218 
    219             // XXX TEST : use a window based on the radial profile numbers: max is skyRadius, min is RADIUS
    220             // if we lack the skyRadius (eg MATCHED sources), go to the default value
    221             float maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     323            // On first iteration set window radius to sky radius (if valid) on second iteration
     324            // use a factor times the previous radial moment value up to a maximum value that
     325            // depends on the surface brightness of the source
     326            float maxWindow;
     327            if (j == 0) {
     328                maxWindow = isfinite(source->skyRadius) ? source->skyRadius : RADIUS;
     329            } else {
     330                if (KRON_SB_MIN_DIVISOR) {
     331                    if (isfinite(source->moments->KronFlux) && (source->moments->KronFlux > 0)) {
     332                        // Limit window radius based on surface brightness
     333                        float Rmax = sqrt(source->moments->KronFlux) / KRON_SB_MIN_DIVISOR;
     334
     335                        if (source->moments->Mrf > 0) {
     336                            maxWindow = PS_MIN(6.0*source->moments->Mrf, Rmax);
     337                        } else {
     338                            maxWindow = Rmax;
     339                        }
     340                    } else {
     341                        maxWindow = RADIUS;
     342                    }
     343                } else {
     344                    // old code
     345                    maxWindow = isfinite(source->moments->Mrf) ? 6.0*source->moments->Mrf : RADIUS;
     346                }
     347            }
    222348            float windowRadius = PS_MAX(RADIUS, maxWindow);
    223349
    224350            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
    225             pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
     351            bool extend = pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
    226352            psAssert (source->pixels, "WTF?");
     353            if (extend && smoothedPixels) {
     354                psFree(source->tmpPtr);
     355                smoothedPixels = psImageSubset(smoothedImage, source->region);
     356                psAssert (smoothedPixels, "WTF?");
     357                source->tmpPtr = (psPtr) smoothedPixels ;
     358            }
     359
    227360
    228361            // clear the window function for this source based on the moments
    229             psphotKronWindowSetSource (source, kronWindow, (j > 0), false);
    230 
    231             // this function populates moments->Mrf,KronFlux,KronFluxErr
    232             psphotKronWindowMag (source, kronWindow, windowRadius, MIN_KRON_RADIUS, maskVal);
    233             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    234 
    235             // set a window function for each source based on the moments
    236             psphotKronWindowSetSource (source, kronWindow, true, true);
     362            // Note: this function also applies cuts on the source and returns false if it
     363            // does not meet the requirements for measuring the Kron Radius or Magnitude.
     364            // Note: that it performs the cuts even if KRON_APPLY_WINDOW is false
     365            if (psphotKronWindowSetSource (source, kronWindow, (j > 0), false, KRON_APPLY_WINDOW)) {
     366
     367                // this function populates moments->Mrf,KronFlux,KronFluxErr
     368                psphotKronWindowMag (source, kronWindow, windowRadius, MIN_KRON_RADIUS, maskVal, KRON_APPLY_WEIGHT, smoothedPixels);
     369                psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     370
     371                // set a window function for each source based on the moments
     372                psphotKronWindowSetSource (source, kronWindow, true, true, KRON_APPLY_WINDOW);
     373            }
    237374
    238375            // if we subtracted it above, re-subtract the object, leave local sky
    239376            if (reSubtract) {
    240                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     377                pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     378                if (smoothedPixels) {
     379                    pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, false, maskVal, 0, 0);
     380                }
    241381            }
    242382        }
    243383    }
     384
    244385    return true;
    245386}
    246387
    247 bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal) {
     388bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal,
     389    bool applyWeight, psImage *smoothedPixels) {
    248390
    249391    PS_ASSERT_PTR_NON_NULL(source, false);
     
    253395
    254396    psF32 R2 = PS_SQR(radius);
    255     float rsigma2 = 0.5 / PS_SQR(radius/2.0);
     397    float rsigma2 =  applyWeight ? 0.5 / R2 : 0;
    256398
    257399    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    266408    // Xn  = SUM (x - xc)^n * (z - sky)
    267409
     410
    268411    psF32 RF = 0.0;
    269412    psF32 RS = 0.0;
     
    284427    int Ywo = source->pixels->row0;
    285428
    286     psF32 **vPix = source->pixels->data.F32;
     429    psF32 **vPix;
     430    if (smoothedPixels) {
     431        vPix = smoothedPixels->data.F32;
     432    } else {
     433        vPix = source->pixels->data.F32;
     434    }
    287435    psF32 **vWin = kronWindow->data.F32;
    288436    psF32 **vWgt = source->variance->data.F32;
     
    357505    float Var = 0.0;
    358506    float Win = 0.0;
     507
     508    // set vPix to the source pixels (it may have been set to the
     509    // smoothed image above)
     510    vPix = source->pixels->data.F32;
     511
    359512
    360513    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     
    395548}
    396549
    397 bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert) {
     550bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert, bool applyWindow) {
    398551
    399552    if (!source) return false;
     
    402555    if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
    403556    if (source->type == PM_SOURCE_TYPE_SATURATED) return false;
     557    if (!(source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED)) return false;
     558    if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) return false;
    404559    psAssert(kronWindow, "need a window");
     560
     561    if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
     562
     563    if (!applyWindow) {
     564        return true;
     565    }
    405566
    406567    // we have a source with moments Mx, My, Mxx, Mxy, Myy.  we just need to define a Gaussian that has
     
    413574    float Yo = source->moments->My;
    414575
    415     float Mxx = source->moments->Mxx;
    416     float Mxy = source->moments->Mxy;
    417     float Myy = source->moments->Myy;
    418 
    419     float Mmajor = 0.5*(Mxx + Myy) + 0.5*sqrt(PS_SQR(Mxx - Myy) + 4.0*PS_SQR(Mxy));
    420     float Mminor = 0.5*(Mxx + Myy) - 0.5*sqrt(PS_SQR(Mxx - Myy) + 4.0*PS_SQR(Mxy));
    421 
    422     // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width
    423     float scale = PS_SQR(0.5 * source->moments->Mrf) / Mmajor;
    424 
    425     float Sxx = scale * Mmajor * Mminor / Myy; // sigma_x^2
    426     float Sxy = Mxy / (scale * Mmajor * Mminor);
    427     float Syy = scale * Mmajor * Mminor / Mxx; // sigma_y^2
    428 
    429     float Smajor = sqrt(Mmajor);
     576    psEllipseMoments moments;
     577    moments.x2 = source->moments->Mxx;
     578    moments.y2 = source->moments->Myy;
     579    moments.xy = source->moments->Mxy;
     580
     581    psEllipseAxes axes = psEllipseMomentsToAxes(moments, 20.0);
     582    if (! (isfinite(axes.major) && isfinite(axes.minor) && isfinite(axes.theta)) ) {
     583        // Shall we log a proper warning? This happens often with matched sources (forced photometry)
     584        // fprintf(dump, "invalid axes found id: %4d major: %f minor: %f theta: %f\n", source->id, axes.major, axes.minor, axes.theta);
     585        return false;
     586    }
     587
     588    // Why this factor of 0.5 ?
     589    float scale = 0.5 * source->moments->Mrf / axes.major;
     590    axes.major *= scale;
     591    axes.minor *= scale;
     592
     593    psEllipseShape shape = psEllipseAxesToShape(axes);
     594    if (! (isfinite(shape.sx) && isfinite(shape.sy) && isfinite(shape.sxy)) ) {
     595        // Shall we log a proper warning? This happens often with matched sources (forced photometry)
     596        // fprintf(dump, "invalid shape found id: %d sx: %f sy %f sxy: %f\n", source->id, shape.sx, shape.sy, shape.sxy);
     597        return false;
     598    }
     599
     600    float Smajor = axes.major;
    430601
    431602    int minX = PS_MIN(PS_MAX(Xo - 5*Smajor, 0), Nx - 1);
     
    434605    int maxY = PS_MIN(PS_MAX(Yo + 5*Smajor, 0), Ny - 1);
    435606
    436     float rMxx = 0.5 / Sxx;
    437     float rMyy = 0.5 / Syy;
    438    
     607    float rMxx = 0.5 / PS_SQR(shape.sx);
     608    float rMyy = 0.5 / PS_SQR(shape.sy);
     609    float Sxy = -1. * shape.sxy;    // factor of -1 is included to match the previous window function
     610                                    // implementation. XXX: Is this correct?
     611
    439612    for (int iy = minY; iy < maxY; iy++) {
    440613        for (int ix = minX; ix < maxX; ix++) {
     
    447620            float f = insert ? 1.001 - exp(-z) : 1.0 / (1.001 - exp(-z));
    448621
    449             kronWindow->data.F32[iy][ix] *= f;
     622            kronWindow->data.F32[iy][ix] *= f;
    450623        }
    451624    }
     625
    452626    return true;
    453627}
Note: See TracChangeset for help on using the changeset viewer.