IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 26, 2010, 9:18:39 AM (16 years ago)
Author:
Serge CHASTEL
Message:

Merging trunk in branch

Location:
branches/sc_branches/trunkTest
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/sc_branches/trunkTest

  • branches/sc_branches/trunkTest/psphot

    • Property svn:mergeinfo deleted
  • branches/sc_branches/trunkTest/psphot/src/psphotSourceFits.c

    r26894 r29060  
    22
    33// given a source with an existing modelPSF, attempt a full PSF fit, subtract if successful
    4 // XXX this function does not call pmSourceFitModelInit : fix this?
    54
    65static int NfitPSF = 0;
     
    87static int NfitDBL = 0;
    98static int NfitEXT = 0;
     9static int NfitPCM = 0;
    1010
    1111bool psphotFitInit (int nThreads) {
     
    1818
    1919    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "fitted %5d psf, %5d blend, %5d ext, %5d dbl : %6.2f sec\n",
    20              NfitPSF, NfitBlend, NfitEXT, NfitDBL, psTimerMark ("psphot.fits"));
    21     return true;
    22 }
    23 
    24 bool psphotFitBlend (pmReadout *readout, pmSource *source, pmPSF *psf, psImageMaskType maskVal, psImageMaskType markVal) {
     20              NfitPSF, NfitBlend, NfitEXT, NfitDBL, psTimerMark ("psphot.fits"));
     21    return true;
     22}
     23
     24bool psphotFitBlend (pmReadout *readout, pmSource *source, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
    2525
    2626    float x, y, dR;
     27
     28    pmSourceFitOptions options = *fitOptions;
    2729
    2830    // maskVal is used to test for rejected pixels, and must include markVal
     
    3133    // if this source is not a possible blend, just fit as PSF
    3234    if ((source->blends == NULL) || (source->mode & PM_SOURCE_MODE_SATSTAR)) {
    33         bool status = psphotFitPSF (readout, source, psf, maskVal, markVal);
     35        bool status = psphotFitPSF (readout, source, psf, fitOptions, maskVal, markVal);
    3436        return status;
    3537    }
     
    9193
    9294    // fit PSF model
    93     pmSourceFitSet (source, modelSet, PM_SOURCE_FIT_PSF, maskVal);
     95    options.mode = PM_SOURCE_FIT_PSF;
     96    pmSourceFitSet (source, modelSet, &options, maskVal);
    9497
    9598    // clear the circular mask
     
    154157}
    155158
    156 bool psphotFitPSF (pmReadout *readout, pmSource *source, pmPSF *psf, psImageMaskType maskVal, psImageMaskType markVal) {
     159bool psphotFitPSF (pmReadout *readout, pmSource *source, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
    157160
    158161    double chiTrend;
     162    pmSourceFitOptions options = *fitOptions;
    159163
    160164    // maskVal is used to test for rejected pixels, and must include markVal
     
    171175
    172176    // fit PSF model (set/unset the pixel mask)
    173     pmSourceFitModel (source, PSF, PM_SOURCE_FIT_PSF, maskVal);
     177    options.mode = PM_SOURCE_FIT_PSF;
     178    pmSourceFitModel (source, PSF, &options, maskVal);
    174179
    175180    if (!isfinite(PSF->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
     
    199204}
    200205
     206// save a local, static copy of the EXT model type so we don't have to lookup for each object
    201207static pmModelType modelTypeEXT;
    202208
    203 bool psphotInitLimitsEXT (psMetadata *recipe) {
     209bool psphotInitLimitsEXT (psMetadata *recipe, pmReadout *readout) {
    204210
    205211    bool status;
     
    208214    char *modelNameEXT = psMetadataLookupStr (&status, recipe, "EXT_MODEL");
    209215    modelTypeEXT = pmModelClassGetType (modelNameEXT);
    210     psphotInitRadiusEXT (recipe, modelTypeEXT);
    211 
    212     return true;
    213 }
    214 
    215 bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *newSources, pmPSF *psf, psImageMaskType maskVal, psImageMaskType markVal) {
    216 
     216
     217    psphotInitRadiusEXT (recipe, readout);
     218
     219    return true;
     220}
     221
     222bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *newSources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
     223
     224    float radius;
    217225    bool okEXT, okDBL;
    218226    float chiEXT, chiDBL;
     
    222230    pmModel *EXT = NULL;
    223231    psArray *DBL = NULL;
     232    pmMoments psfMoments;
    224233
    225234    // skip the source if we don't think it is extended
     235    // XXX are these robust, or do we have better info from the source-size analysis??
    226236    if (source->type == PM_SOURCE_TYPE_UNKNOWN) return false;
    227237    if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
     
    229239
    230240    // set the radius based on the footprint (also sets the mask pixels)
    231     float radius = psphotSetRadiusEXT (readout, source, markVal);
     241    if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) return false;
    232242
    233243    // XXX note that this changes the source moments that are published...
     244    // XXX all published moments should use the same measurement
    234245    // recalculate the source moments using the larger extended-source moments radius
    235246    // at this stage, skip Gaussian windowing, and do not clip pixels by S/N
    236247    // this uses the footprint to judge both radius and aperture?
    237     if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) return false;
     248    // XXX save the psf-based moments for output
     249    psfMoments = *source->moments;
     250    if (!pmSourceMoments (source, radius, 0.0, 0.5, maskVal)) {
     251      *source->moments = psfMoments;
     252      return false;
     253    }
    238254
    239255    psTrace ("psphot", 5, "trying blob...\n");
     
    244260    // this temporary source is used as a place-holder by the psphotEval functions below
    245261    tmpSrc = pmSourceAlloc ();
    246 
    247     // XXX need to handle failures better here
    248     EXT = psphotFitEXT (readout, source, modelTypeEXT, maskVal, markVal);
    249     if (!EXT) goto escape;
    250     if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape;
    251 
    252     okEXT = psphotEvalEXT (tmpSrc, EXT);
    253     chiEXT = EXT ? EXT->chisq / EXT->nDOF : NAN;
    254 
    255     // DBL will always be defined, but DBL->data[n] might not
    256     DBL = psphotFitDBL (readout, source, maskVal, markVal);
    257     if (!DBL) goto escape;
    258     if (!DBL->n) goto escape;
    259 
    260     okDBL  = psphotEvalDBL (tmpSrc, DBL->data[0]);
    261     okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]);
    262     // XXX should I keep / save the flags set in the eval functions?
     262    {
     263        // DBL will always be defined, but DBL->data[n] might not
     264        DBL = psphotFitDBL (readout, source, fitOptions, maskVal, markVal);
     265        if (!DBL) goto escape;
     266        if (!DBL->n) goto escape;
     267
     268        okDBL  = psphotEvalDBL (tmpSrc, DBL->data[0]);
     269        okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]);
     270        // XXX should I keep / save the flags set in the eval functions?
     271
     272        // correct first model chisqs for flux trend
     273        chiDBL = NAN;
     274        ONE = DBL->data[0];
     275        if (ONE) {
     276            if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
     277            chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);
     278            ONE->chisqNorm = ONE->chisq / chiTrend;
     279            chiDBL = ONE->chisq / ONE->nDOF; // save chisq for double-star/galaxy comparison
     280            ONE->fitRadius = radius;
     281        }
     282
     283        // correct second model chisqs for flux trend
     284        ONE = DBL->data[1];
     285        if (ONE) {
     286            if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
     287            chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);
     288            ONE->chisqNorm = ONE->chisq / chiTrend;
     289            ONE->fitRadius = radius;
     290        }
     291    }
     292
     293    {
     294        // XXX need to handle failures better here
     295        EXT = psphotFitEXT (readout, source, fitOptions, modelTypeEXT, maskVal, markVal);
     296        if (!EXT) goto escape;
     297        if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape;
     298
     299        okEXT = psphotEvalEXT (tmpSrc, EXT);
     300        chiEXT = EXT ? EXT->chisq / EXT->nDOF : NAN;
     301    }
    263302
    264303    // clear the circular mask
    265304    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    266 
    267     // correct first model chisqs for flux trend
    268     chiDBL = NAN;
    269     ONE = DBL->data[0];
    270     if (ONE) {
    271         if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
    272       chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);
    273       ONE->chisqNorm = ONE->chisq / chiTrend;
    274       chiDBL = ONE->chisq / ONE->nDOF; // save chisq for double-star/galaxy comparison
    275     }
    276 
    277     // correct second model chisqs for flux trend
    278     ONE = DBL->data[1];
    279     if (ONE) {
    280         if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");
    281       chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);
    282       ONE->chisqNorm = ONE->chisq / chiTrend;
    283     }
    284305
    285306    psFree (tmpSrc);
     
    298319
    299320    // both models failed; reject them both
    300     // XXX -- change type flags to psf in this case and keep original moments?
     321    // XXX -- change type flags to psf in this case, and make sure we subtract it?
     322    // reset the psf moments
     323    *source->moments = psfMoments;
     324
    301325    psFree (EXT);
    302326    psFree (DBL);
     
    308332
    309333    // save new model
     334    // XXX save the correct radius...
    310335    source->modelEXT = EXT;
    311     source->modelEXT->fitRadius = radius;
    312336    source->type = PM_SOURCE_TYPE_EXTENDED;
    313337    source->mode |= PM_SOURCE_MODE_EXTMODEL;
     
    327351# endif
    328352
     353    // reset the psf moments
     354    *source->moments = psfMoments;
    329355    return true;
    330356
     
    337363    source->modelPSF = psMemIncrRefCounter (DBL->data[0]);
    338364    source->mode     |= PM_SOURCE_MODE_PAIR;
    339     source->modelPSF->fitRadius = radius;
    340365
    341366    // copy most data from the primary source (modelEXT, blends stay NULL)
    342     pmSource *newSrc = pmSourceCopy (source);
     367    pmSource *newSrc = pmSourceCopyData (source);
    343368    newSrc->modelPSF = psMemIncrRefCounter (DBL->data[1]);
    344     newSrc->modelPSF->fitRadius = radius;
    345369
    346370    // build cached models and subtract
     
    365389# endif
    366390
     391    // reset the (original) psf moments
     392    *source->moments = psfMoments;
     393    *newSrc->moments = psfMoments;
     394
    367395    psArrayAdd (newSources, 100, newSrc);
    368396    psFree (newSrc);
     
    371399
    372400escape:
     401    // reset the psf moments
     402    *source->moments = psfMoments;
    373403    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    374404    psFree (tmpSrc);
     
    379409
    380410// fit a double PSF source to an extended blob
    381 psArray *psphotFitDBL (pmReadout *readout, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) {
     411psArray *psphotFitDBL (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
    382412
    383413    float dx, dy;
     
    387417    psEllipseMoments moments;
    388418    psArray *modelSet;
     419
     420    pmSourceFitOptions options = *fitOptions;
    389421
    390422    NfitDBL ++;
     
    403435    axes = psEllipseMomentsToAxes (moments, 20.0);
    404436
     437    if (isnan(axes.major)) return NULL;
     438    if (isnan(axes.minor)) return NULL;
     439    if (isnan(axes.theta)) return NULL;
     440
    405441    // XXX this is really arbitrary: 4 pixel separation?
    406442    dx = 2 * cos (axes.theta);
     
    426462
    427463    // fit PSF model (set/unset the pixel mask)
    428     pmSourceFitSet (source, modelSet, PM_SOURCE_FIT_PSF, maskVal);
     464    options.mode = PM_SOURCE_FIT_PSF;
     465    pmSourceFitSet (source, modelSet, &options, maskVal);
    429466    return (modelSet);
    430467}
    431468
    432 pmModel *psphotFitEXT (pmReadout *readout, pmSource *source, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal) {
     469pmModel *psphotFitEXT (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal) {
     470
     471    if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) {
     472        psTrace ("psphot", 5, "problem source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
     473    }
     474
     475    pmSourceFitOptions options = *fitOptions;
    433476
    434477    NfitEXT ++;
     
    438481
    439482    // use the source moments, etc to guess basic model parameters
    440     pmModel *EXT = pmSourceModelGuess (source, modelType);
    441     if (!EXT) {
     483    pmModel *model = pmSourceModelGuess (source, modelType);
     484    if (!model) {
    442485        psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
    443486        return NULL;
    444487    }
    445488
     489    // for sersic models, use a grid search to choose an index, then float the params there
     490    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     491        // for the test fits, use a somewhat smaller radius
     492        psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
     493        psphotFitSersicIndex (model, readout, source, fitOptions, maskVal, markVal);
     494    }
     495
     496    if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
     497        psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0);
     498    }
     499
     500    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     501        options.mode = PM_SOURCE_FIT_NO_INDEX;
     502    } else {
     503        options.mode = PM_SOURCE_FIT_EXT;
     504    }
     505
     506    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
     507    pmSourceFitModel (source, model, &options, maskVal);
     508    // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     509
     510    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     511    return (model);
     512}
     513
     514pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     515
    446516    if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) {
    447517        psTrace ("psphot", 5, "problem source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
    448518    }
    449519
     520    pmSourceFitOptions options = *fitOptions;
     521
     522    NfitPCM ++;
     523
     524    // maskVal is used to test for rejected pixels, and must include markVal
     525    maskVal |= markVal;
     526
     527    // allocate the model
     528    pmModel *model = pmModelAlloc(modelType);
     529    if (!model) {
     530        return NULL;
     531    }
     532
     533    pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize);
     534    if (!pcm) {
     535        psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
     536        model->flags |= PM_MODEL_STATUS_BADARGS; // XXX this is probably already set in pmPCMinit
     537        return model;
     538    }
     539
     540    // use the source moments, etc to guess basic model parameters
     541    if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) {
     542        psFree (pcm);
     543        model->flags |= PM_MODEL_STATUS_BADARGS;
     544        return model;
     545    }
     546
     547    // for sersic models, use a grid search to choose an index, then float the params there
     548    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     549        // for the test fits, use a somewhat smaller radius
     550        psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
     551
     552        if (!psphotFitSersicIndexPCM (pcm, readout, source, fitOptions, maskVal, markVal, psfSize)) {
     553            model->flags |= PM_MODEL_STATUS_BADARGS;
     554            return model;
     555        }
     556    }
     557
     558    if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
     559        psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0);
     560    }
     561
     562    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     563        options.mode = PM_SOURCE_FIT_NO_INDEX;
     564    } else {
     565        options.mode = PM_SOURCE_FIT_EXT;
     566    }
     567    // update the pcm elements if we have changed the circumstance (options.mode or source->pixels)
     568    pmPCMupdate(pcm, source, &options, model);
     569
     570    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);
     571    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     572    // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     573
     574    // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     575    psFree (pcm);
     576
     577    return model;
     578}
     579
     580// note that these should be 1/2n of the standard sersic index
     581float indexGuess[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083};
     582# define N_INDEX_GUESS 6
     583
     584// A sersic model is very sensitive to the index.  attempt to find the index first by grid search in just the index
     585// for a sersic model, attempt to fit just the index and normalization with a modest number of iterations
     586bool psphotFitSersicIndex (pmModel *model, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) {
     587
     588    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     589
     590    pmSourceFitOptions options = *fitOptions;
     591   
    450592    // fit EXT (not PSF) model (set/unset the pixel mask)
    451     pmSourceFitModel (source, EXT, PM_SOURCE_FIT_EXT, maskVal);
    452     return (EXT);
    453 }
     593    options.mode = PM_SOURCE_FIT_NO_INDEX;
     594    options.nIter = 4;
     595
     596    int iMin = -1;
     597    float xMin = NAN;
     598    float chiSquare[N_INDEX_GUESS];
     599
     600    for (int i = 0; i < N_INDEX_GUESS; i++) {
     601        model->params->data.F32[PM_PAR_7] = indexGuess[i];
     602
     603        if (!model->modelGuess(model, source)) {
     604            model->flags |= PM_MODEL_STATUS_BADARGS;
     605            return false;
     606        }
     607
     608        // each time we change the model guess, we need to adjust the radius
     609        // XXX this did not work : we do not need such a large radius -- just uses moments-based radius
     610        if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {
     611            psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
     612        }
     613       
     614        pmSourceFitModel (source, model, &options, maskVal);
     615        // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     616
     617        chiSquare[i] = model->chisqNorm;
     618        if (i == 0) {
     619            xMin = chiSquare[i];
     620            iMin = i;
     621        } else {
     622            if (chiSquare[i] < xMin) {
     623                xMin = chiSquare[i];
     624                iMin = i;
     625            }
     626        }
     627    }
     628    assert (iMin >= 0);
     629
     630    model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it
     631    model->params->data.F32[PM_PAR_7] = indexGuess[iMin];
     632    model->modelGuess(model, source);
     633
     634    // each time we change the model guess, we need to adjust the radius
     635    // if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {
     636    //  psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal);
     637    // }
     638
     639    return true;
     640}
     641
     642// A sersic model is very sensitive to the index.  attempt to find the index first by grid search in just the index
     643// for a sersic model, attempt to fit just the index and normalization with a modest number of iterations
     644bool psphotFitSersicIndexPCM (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     645
     646    pmModel *model = pcm->modelConv;
     647
     648    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     649
     650    pmSourceFitOptions options = *fitOptions;
     651   
     652    // fit EXT (not PSF) model (set/unset the pixel mask)
     653    options.mode = PM_SOURCE_FIT_NO_INDEX;
     654    options.nIter = 4;
     655
     656    // update the pcm elements if we have changed the circumstance (here, options.mode)
     657    pmPCMupdate(pcm, source, &options, model);
     658
     659    int iMin = -1;
     660    float xMin = NAN;
     661    float chiSquare[N_INDEX_GUESS];
     662
     663    for (int i = 0; i < N_INDEX_GUESS; i++) {
     664        model->params->data.F32[PM_PAR_7] = indexGuess[i];
     665       
     666        if (!model->modelGuess(model, source)) {
     667            model->flags |= PM_MODEL_STATUS_BADARGS;
     668            return false;
     669        }
     670
     671        // each time we change the model guess, we need to adjust the radius
     672        // XXX this did not work : we do not need such a large radius -- just uses moments-based radius
     673        if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {
     674            psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);
     675        }
     676       
     677# if (0)
     678        pmSourceFitModel (source, model, &options, maskVal);
     679# else
     680        pmSourceModelGuessPCM(pcm, source, maskVal, markVal);
     681        pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     682# endif
     683        // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
     684
     685        chiSquare[i] = model->chisq;
     686        if (i == 0) {
     687            xMin = chiSquare[i];
     688            iMin = i;
     689        } else {
     690            if (chiSquare[i] < xMin) {
     691                xMin = chiSquare[i];
     692                iMin = i;
     693            }
     694        }
     695    }
     696    assert (iMin >= 0);
     697   
     698    model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it
     699    model->params->data.F32[PM_PAR_7] = indexGuess[iMin];
     700
     701    pmSourceModelGuessPCM(pcm, source, maskVal, markVal);
     702
     703    return true;
     704}
Note: See TracChangeset for help on using the changeset viewer.