IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36086 for trunk/psphot/src


Ignore:
Timestamp:
Aug 31, 2013, 6:02:26 AM (13 years ago)
Author:
eugene
Message:

merge changes from EAM branch (update tap script for galaxies; count deblended satstars for log message; scale down EXT window a bit for speed (OK?); enable interactive mode for PCM fitting; allow NONCONVERGE extended fit models to succeed; init EXT model fits with EXT_AND_SKY just in case; extra verbosity and various experiments on the index iterations)

Location:
trunk/psphot
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src

  • trunk/psphot/src/psphotBlendFit.c

    r35769 r36086  
    273273        pmSource *source = sources->data[i];
    274274
     275# if (0)
    275276        int TEST_ON = false;
    276 # if (0)
    277277# define TEST_X 653
    278278# define TEST_Y 466
     
    342342        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    343343            if (psphotFitBlob (readout, source, newSources, psf, fitOptions, maskVal, markVal)) {
     344# if (PS_TRACE_ON)
    344345                if (TEST_ON) {
    345346                    psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    346347                }
     348# endif
    347349                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
    348350                Next ++;
     
    351353        } else {
    352354            if (psphotFitBlend (readout, source, psf, fitOptions, maskVal, markVal)) {
     355# if (PS_TRACE_ON)
    353356                if (TEST_ON) {
    354357                    psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    355358                }
     359# endif
    356360                source->type = PM_SOURCE_TYPE_STAR;
    357361                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
  • trunk/psphot/src/psphotDeblendSatstars.c

    r34708 r36086  
    128128    // int display = psphotKapaChannel (1);
    129129    // psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0);
     130
     131    int Nsatstar = 0;
    130132
    131133    // examine sources in decreasing SN order
     
    179181        source->mode2 |= PM_SOURCE_MODE2_SATSTAR_PROFILE; // and we have in fact subtracted the profile
    180182
     183        Nsatstar ++;
     184
    181185        // XXX visualize, model, and subtract
    182186        // if (!psphotVisualRadialProfileSatstar (source, maskVal)) {
     
    192196    psFree (index);
    193197
    194     psLogMsg ("psphot", PS_LOG_INFO, "deblend satstar: %f sec\n", psTimerMark ("psphot.deblend.sat"));
     198    psLogMsg ("psphot", PS_LOG_INFO, "deblend %d satstars: %f sec\n", Nsatstar, psTimerMark ("psphot.deblend.sat"));
    195199    return true;
    196200}
  • trunk/psphot/src/psphotExtendedSourceFits.c

    r35769 r36086  
    6565    psphotVisualShowImage(readout);
    6666
     67    // psphotSaveImage (NULL, readout->image, "test.01.fits");
     68
    6769    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    6870    psAssert (detections, "missing detections?");
     
    123125    }
    124126
     127    // perform full extended source non-linear fits?
     128    bool isInteractive = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS_INTERACTIVE");
     129    if (!status) isInteractive = false;
     130
    125131    // Define source fitting parameters for extended source fits
    126132    pmSourceFitOptions *fitOptions = pmSourceFitOptionsAlloc();
    127     fitOptions->mode           = PM_SOURCE_FIT_EXT;
     133    fitOptions->mode           = PM_SOURCE_FIT_EXT_AND_SKY;
    128134    fitOptions->saveCovariance = true;  // XXX make this a user option?
    129135    fitOptions->covarFactor    = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     
    134140    fitOptions->gainFactorMode   = gainFactorMode;
    135141    fitOptions->chisqConvergence = chisqConvergence;
     142    fitOptions->isInteractive    = isInteractive;
    136143
    137144    // maskVal is used to test for rejected pixels, and must include markVal
     
    296303            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
    297304
    298 // set this to 0 to run without threading
    299 # if (1)           
    300             if (!psThreadJobAddPending(job)) {
    301                 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    302                 psFree(AnalysisRegion);
    303                 psFree (fitOptions);
    304                 psFree (models);
    305                 psphotSersicModelClassCleanup();
    306                 return false;
    307             }
    308 # else
    309             if (!psphotExtendedSourceFits_Threaded(job)) {
    310                 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    311                 psFree(AnalysisRegion);
    312                 psFree (fitOptions);
    313                 psFree (models);
    314                 psphotSersicModelClassCleanup();
    315                 return false;
     305// XXX TEST
     306            if (!isInteractive) {
     307                if (!psThreadJobAddPending(job)) {
     308                    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     309                    psFree(AnalysisRegion);
     310                    psFree (fitOptions);
     311                    psFree (models);
     312                    psphotSersicModelClassCleanup();
     313                    return false;
     314                }
     315            } else {
     316                // run without threading
     317                if (!psphotExtendedSourceFits_Threaded(job)) {
     318                    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     319                    psFree(AnalysisRegion);
     320                    psFree (fitOptions);
     321                    psFree (models);
     322                    psphotSersicModelClassCleanup();
     323                    return false;
     324                }
     325                psScalar *scalar = NULL;
     326                scalar = job->args->data[9];
     327                Next += scalar->data.S32;
     328                scalar = job->args->data[10];
     329                Nconvolve += scalar->data.S32;
     330                scalar = job->args->data[11];
     331                NconvolvePass += scalar->data.S32;
     332                scalar = job->args->data[12];
     333                Nplain += scalar->data.S32;
     334                scalar = job->args->data[13];
     335                NplainPass += scalar->data.S32;
     336                scalar = job->args->data[14];
     337                Nfaint += scalar->data.S32;
     338                scalar = job->args->data[15];
     339                Nfail += scalar->data.S32;
     340                psFree(job->args->data[3]); // iterator allocated above
     341                psFree(job);
    316342            }
    317             psScalar *scalar = NULL;
    318             scalar = job->args->data[9];
    319             Next += scalar->data.S32;
    320             scalar = job->args->data[10];
    321             Nconvolve += scalar->data.S32;
    322             scalar = job->args->data[11];
    323             NconvolvePass += scalar->data.S32;
    324             scalar = job->args->data[12];
    325             Nplain += scalar->data.S32;
    326             scalar = job->args->data[13];
    327             NplainPass += scalar->data.S32;
    328             scalar = job->args->data[14];
    329             Nfaint += scalar->data.S32;
    330             scalar = job->args->data[15];
    331             Nfail += scalar->data.S32;
    332             psFree(job->args->data[3]); // iterator allocated above
    333             psFree(job);
    334 # endif
    335343        }
    336344
     
    378386    psphotSersicModelClassCleanup();
    379387
     388    // psphotSaveImage (NULL, readout->image, "test.02.fits");
     389
    380390    psphotVisualShowResidualImage (readout, false);
    381391
     
    521531                  psFree (source->modelFlux);
    522532                  source->modelFlux = NULL;
     533                  // if ((fabs(source->peak->xf - 2572) < 20) && (fabs(source->peak->yf - 5874) < 20)) {
     534                  //   fprintf (stderr, "test object\n");
     535                  // }
     536
    523537                  modelFit = psphotFitEXT (modelFit, readout, source, fitOptions, modelType, maskVal, markVal);
    524538                  if (!modelFit) {
     
    544558                      float Ymax = PAR[PM_PAR_YPOS] + 0.5*PAR[PM_PAR_LENGTH]*cos(PAR[PM_PAR_THETA]);
    545559
    546                       if (false && (source->peak->xf > 1100) &&
    547                           (source->peak->xf < 1400) &&
    548                           (source->peak->yf < 245)) {
     560                      if ((fabs(source->peak->xf - 2572) < 20) && (fabs(source->peak->yf - 5874) < 20)) {
    549561                          fprintf (stderr, "src vs fit : %d %d - %d %d | %f %f - %f %f\n",
    550562                                   source->pixels->col0, source->pixels->row0,
     
    579591
    580592            if (model->flags & (PM_MODEL_STATUS_BADARGS)) continue;
    581             if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue;
     593            // if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue;
    582594            if (model->flags & (PM_MODEL_STATUS_OFFIMAGE)) continue;
    583595
     
    598610          pmSourceCacheModel (source, maskVal);
    599611
     612          pmModel *model = source->modelFits->data[0];
     613          int flags = 0xffffffff;
     614          if (model) {
     615            flags = model->flags;
     616          }
     617
     618          fprintf (stderr, "failed to fit extended source model to object %d @ %f, %f (%x)\n", source->id, source->moments->Mx, source->moments->My, flags);
    600619          pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    601620
     
    615634        // cache the model flux
    616635        if (source->modelEXT->isPCM) {
     636            // fprintf (stderr, "subtract PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
    617637            pmPCMCacheModel (source, maskVal, psfSize);
    618638        } else {
     639            // fprintf (stderr, "subtract non-PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My);
    619640            pmSourceCacheModel (source, maskVal);
    620641        }
  • trunk/psphot/src/psphotRadiusChecks.c

    r32348 r36086  
    171171# undef MIN_WINDOW
    172172
     173// XXX EAM : 20130724 : for a test, double the window size parameters
     174// # define MIN_WINDOW 10.0
     175// # define SCALE1 7.0
    173176# define MIN_WINDOW 5.0
    174 # define SCALE1 5.0
     177# define SCALE1 3.0
    175178# define PAD_WINDOW 3.0
    176179
  • trunk/psphot/src/psphotSourceFits.c

    r35769 r36086  
    559559
    560560# define TIMING 0
     561# define EXTRA_VERBOSE 0
     562
     563bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize);
     564bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
     565bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
     566bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
    561567
    562568pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     
    580586
    581587    float t1, t2, t4, t5;
     588    t1 = t2 = t4 = t5 = 0.0;
    582589    if (TIMING) { psTimerStart ("psphotFitPCM"); }
     590
     591    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
     592        options.mode = PM_SOURCE_FIT_NO_INDEX; // XXX note that there may be a conflict with psphotExtendedSourceFits.c:133
     593        options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     594        // if we are ever (in a given psphot implementation) going to fit a parameter, we must set the options here to include
     595        // that parameter (otherwise pmPCMupdate will fail to allocate the dmodelFlux image)
     596        // thus, if the sersic analysis below uses an index fit, need to use this EXT_AND_SKY mode for init
     597    } else {
     598        options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     599    }
    583600
    584601    pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize);
     
    594611    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    595612        // use the source moments, etc to guess basic model parameters
    596         if (!psphotSersicModelClassGuessPCM (pcm, source)) {
     613        if (!psphotSersicModelGuessPCM (pcm, source, maskVal, psfSize)) {
    597614            psFree (pcm);
    598615            model->flags |= PM_MODEL_STATUS_BADARGS;
     616            return model;
     617        }
     618        if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }
     619
     620        // psphotFitSersicShapeAndIndex (pcm, readout, source, fitOptions, maskVal, markVal, psfSize);
     621        options.mode = PM_SOURCE_FIT_NO_INDEX;
     622        if (!psphotFitSersicShapeAndIndexGridAuto (pcm, readout, source, &options, maskVal, markVal, psfSize)) {
     623            psFree (pcm);
     624            model->flags |= PM_MODEL_STATUS_BADARGS;
     625            psError(PS_ERR_UNKNOWN, true, "Failed to find a index & shape");
     626            psErrorClear (); // clear the polynomial error
    599627            return model;
    600628        }
     
    608636    }
    609637
    610     if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }
    611 
    612     if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
    613         options.mode = PM_SOURCE_FIT_NO_INDEX;
    614     } else {
    615         options.mode = PM_SOURCE_FIT_EXT;
    616     }
    617     // update the pcm elements if we have changed the circumstance (options.mode or source->pixels)
    618     pmPCMupdate(pcm, source, &options, model);
    619638    if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); }
    620639
     
    629648        fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t4, t5);
    630649    }
    631 
    632     // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
     650    if (EXTRA_VERBOSE && !TIMING) {
     651        int nPixBig = source->pixels->numCols * source->pixels->numRows;
     652        float *PAR = model->params->data.F32;
     653        fprintf (stderr, "source %d : %f - %f %f - %f %f %f - %f | nIter: %2d, radius: %6.1f, npix: %5d of %5d, chisq %f\n", source->id, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1], model->nIter, model->fitRadius, model->nPix, nPixBig, model->chisqNorm);
     654    }
     655
    633656    psFree (pcm);
    634657
     
    748771    return true;
    749772}
     773
     774// float indexGuessInv[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083};
     775float indexGuessInv[] = {0.5, 0.4, 0.3, 0.25, 0.20, 0.15, 0.125};
     776# define N_INDEX_GUESS_INV 7
     777
     778// float reffGuess[] = {3.0, 10.0, 20.0, 30.0, 40.0};
     779float reffGuess[] = {0.5, 0.75, 1.0, 1.4, 2.0};
     780# define N_REFF_GUESS 5
     781
     782// A sersic model is very sensitive to the index.  attempt to find the index first by grid search in just the index
     783// for a sersic model, attempt to fit just the index and normalization with a modest number of iterations
     784bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) {
     785
     786    // we get a reasonable guess from:
     787    // * Reff = Kron R1
     788    // * Rmajor / Rminor & Theta from moments
     789    // * Io from total Kron flux
     790
     791    // the guesses are used to fill in PAR:
     792    psF32 *PAR = pcm->modelConv->params->data.F32;
     793
     794    // convert the moments to Major,Minor,Theta
     795    psEllipseMoments moments;
     796
     797    if (!isfinite(source->moments->Mrf)) return false;
     798    if (!isfinite(source->moments->Mxx)) return false;
     799    if (!isfinite(source->moments->Mxy)) return false;
     800    if (!isfinite(source->moments->Myy)) return false;
     801
     802    moments.x2 = source->moments->Mxx;
     803    moments.y2 = source->moments->Myy;
     804    moments.xy = source->moments->Mxy;
     805   
     806    // limit axis ratio < 20.0
     807    psEllipseAxes momentAxes = psEllipseMomentsToAxes (moments, 20.0);
     808
     809    if (0) {
     810        psEllipseAxes guessAxes;
     811        guessAxes.major = source->moments->Mrf;
     812        guessAxes.minor = (momentAxes.minor / momentAxes.minor) * guessAxes.major;
     813        guessAxes.theta = momentAxes.theta;
     814
     815        if (!isfinite(guessAxes.major)) return false;
     816        if (!isfinite(guessAxes.minor)) return false;
     817        if (!isfinite(guessAxes.theta)) return false;
     818
     819        // convert the major,minor,theta to shape parameters for an Reff-like model
     820        pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     821    }
     822
     823    // set the model position
     824    if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) {
     825      return false;
     826    }
     827
     828    // sky is zero (no longer fitted, but not yet deprecated)
     829    PAR[PM_PAR_SKY]  = 0.0;
     830
     831    // for the index loop, use Io = 1.0, use fitted values to determine Io
     832    PAR[PM_PAR_I0] = 1.0;
     833
     834    float xMin = NAN;
     835    float iMin = NAN;
     836    float sMin = NAN;
     837    float rMin = NAN;
     838
     839    // loop over index and Reff, keeping the ARatio and Theta constant?
     840    // loop over index guesses and find the best fit
     841    for (int j = 0; j < N_REFF_GUESS; j++) {
     842
     843        psEllipseAxes guessAxes;
     844        guessAxes.major = reffGuess[j] * source->moments->Mrf;
     845        guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major);
     846        guessAxes.theta = momentAxes.theta;
     847
     848        if (!isfinite(guessAxes.major)) return false;
     849        if (!isfinite(guessAxes.minor)) return false;
     850        if (!isfinite(guessAxes.theta)) return false;
     851
     852        // convert the major,minor,theta to shape parameters for an Reff-like model
     853        pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     854
     855        for (int i = 0; i < N_INDEX_GUESS_INV; i++) {
     856            PAR[PM_PAR_7] = indexGuessInv[i];
     857
     858            // generated the modelFlux
     859            pmPCMMakeModel (source, pcm->modelConv, maskVal, psfSize);
     860       
     861            float YY = 0.0;
     862            float YM = 0.0;
     863            float MM = 0.0;
     864            bool usePoisson = false;
     865
     866            for (int iy = 0; iy < source->pixels->numRows; iy++) {
     867                for (int ix = 0; ix < source->pixels->numCols; ix++) {
     868                    // skip masked points
     869                    if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
     870                        continue;
     871                    }
     872                    // skip zero-variance points
     873                    if (source->variance->data.F32[iy][ix] == 0) {
     874                        continue;
     875                    }
     876                    // skip nan value points
     877                    if (!isfinite(source->pixels->data.F32[iy][ix])) {
     878                        continue;
     879                    }
     880
     881                    float fy = source->pixels->data.F32[iy][ix];
     882                    float fm = source->modelFlux->data.F32[iy][ix];
     883                    float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0;
     884
     885                    YY += PS_SQR(fy) * wt;
     886                    YM += fm * fy * wt;
     887                    MM += PS_SQR(fm) * wt;
     888                }
     889            }
     890
     891            float Io = YM / MM;
     892            float Chisq = YY - 2 * Io * YM + Io * Io * MM;
     893            if (isnan(xMin) || (Chisq < xMin)) {
     894                xMin = Chisq;
     895                iMin = Io;
     896                sMin = indexGuessInv[i];
     897                rMin = reffGuess[j];
     898            }
     899            // fprintf (stderr, "%d | %f %f %f %f | %f %f %f %f", i, indexGuessInv[i], reffGuess[j], Io, Chisq, sMin, rMin, iMin, xMin);
     900            // fprintf (stderr, "\n");
     901        }
     902    }
     903
     904    {
     905        psEllipseAxes guessAxes;
     906        guessAxes.major = rMin * source->moments->Mrf;
     907        guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major);
     908        guessAxes.theta = momentAxes.theta;
     909
     910        if (!isfinite(guessAxes.major)) return false;
     911        if (!isfinite(guessAxes.minor)) return false;
     912        if (!isfinite(guessAxes.theta)) return false;
     913
     914        // convert the major,minor,theta to shape parameters for an Reff-like model
     915        pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true);
     916    }
     917
     918    PAR[PM_PAR_I0] = iMin;
     919    PAR[PM_PAR_7] = sMin;
     920
     921    return true;
     922}
     923
     924// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     925bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     926
     927    pmModel *model = pcm->modelConv;
     928
     929    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     930
     931    pmSourceFitOptions options = *fitOptions;
     932   
     933    for (int i = 0; i < 3; i++) {
     934      // fit EXT (not PSF) model (set/unset the pixel mask)
     935      options.mode = PM_SOURCE_FIT_SHAPE;
     936      options.nIter = 2;
     937
     938      // update the pcm elements if we have changed the circumstance (here, options.mode)
     939      pmPCMupdate(pcm, source, &options, model);
     940     
     941      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     942      if (EXTRA_VERBOSE) {
     943        float *PAR = model->params->data.F32;
     944        fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     945      }
     946     
     947      // fit EXT (not PSF) model (set/unset the pixel mask)
     948      options.mode = PM_SOURCE_FIT_INDEX;
     949      // options.mode = PM_SOURCE_FIT_EXT_AND_SKY;
     950      options.nIter = 30;
     951     
     952      // update the pcm elements if we have changed the circumstance (here, options.mode)
     953      pmPCMupdate(pcm, source, &options, model);
     954     
     955      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     956      if (EXTRA_VERBOSE) {
     957        float *PAR = model->params->data.F32;
     958        fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     959      }
     960    }
     961
     962    // update the pcm elements if we have changed the circumstance (here, options.mode)
     963    pmPCMupdate(pcm, source, fitOptions, model);
     964
     965    return true;
     966}
     967
     968// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     969bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     970
     971    pmModel *model = pcm->modelConv;
     972
     973    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     974
     975    pmSourceFitOptions options = *fitOptions;
     976   
     977    psF32 *PAR = pcm->modelConv->params->data.F32;
     978
     979    options.mode = PM_SOURCE_FIT_SHAPE;
     980    options.nIter = 7;
     981   
     982    // update the pcm elements if we have changed the circumstance (here, options.mode)
     983    pmPCMupdate(pcm, source, &options, model);
     984   
     985    // we have been provided a guess at the index (P[7]) from the list of indexGuessInv
     986
     987    // find the matching indexGuessInv
     988    int nStart = -1;
     989    for (int i = 0; i < N_INDEX_GUESS_INV; i++) {
     990        if (fabs(PAR[PM_PAR_7] - indexGuessInv[i]) < 0.01) {
     991            nStart = i;
     992            break;
     993        }
     994    }
     995    if (nStart == -1) {
     996        fprintf (stderr, "WARNING: could not find start guess %f\n", PAR[PM_PAR_7]);
     997        return false;
     998    }
     999
     1000    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1001    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1002
     1003    PAR[PM_PAR_7] = indexGuessInv[nStart];
     1004    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1005    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1006    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1007    psVectorAppend (chi2, model->chisqNorm);
     1008
     1009    PAR[PM_PAR_7] = (nStart < N_INDEX_GUESS_INV - 1) ? 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]) : 0.1;
     1010    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1011    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1012    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1013    psVectorAppend (chi2, model->chisqNorm);
     1014
     1015    PAR[PM_PAR_7] = (nStart > 0) ? 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]) : 0.55;
     1016    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1017    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1018    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1019    psVectorAppend (chi2, model->chisqNorm);
     1020
     1021    if (chi2->data.F32[1] < chi2->data.F32[2]) {
     1022      if (nStart == N_INDEX_GUESS_INV - 1) {
     1023        PAR[PM_PAR_7] = 0.11;
     1024      } else {
     1025        PAR[PM_PAR_7] = indexGuessInv[nStart + 1];
     1026      }
     1027    } else {
     1028      if (nStart == 0) {
     1029        PAR[PM_PAR_7] = 0.52;
     1030      } else {
     1031        PAR[PM_PAR_7] = indexGuessInv[nStart - 1];
     1032      }
     1033    }
     1034
     1035    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1036    if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1037        psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1038        psFree (chi2);
     1039        psFree (Sidx);
     1040        psFree (poly);
     1041        return false;
     1042    }
     1043
     1044    // where is the minimum of this polynomial fit?
     1045    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0;
     1046
     1047    // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
     1048    Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1049    PAR[PM_PAR_7] = Smin;
     1050
     1051    // return to the original fitting mode (fitOptions)
     1052    pmPCMupdate(pcm, source, fitOptions, model);
     1053
     1054    psFree (chi2);
     1055    psFree (Sidx);
     1056    psFree (poly);
     1057
     1058    return true;
     1059}
     1060
     1061 
     1062// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     1063bool psphotFitSersicShapeAndIndexGridAutoScaled (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     1064
     1065    pmModel *model = pcm->modelConv;
     1066
     1067    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     1068
     1069    pmSourceFitOptions options = *fitOptions;
     1070   
     1071    psF32 *PAR = pcm->modelConv->params->data.F32;
     1072
     1073    options.mode = PM_SOURCE_FIT_SHAPE;
     1074    options.nIter = 5;
     1075   
     1076    // update the pcm elements if we have changed the circumstance (here, options.mode)
     1077    pmPCMupdate(pcm, source, &options, model);
     1078   
     1079    float parStart[8];
     1080    for (int i = 0; i < 8; i++) parStart[i] = PAR[i];
     1081
     1082    // we start with a guess at the index (P[7])
     1083
     1084    // get chisq for P[7], P[7]*1.1, P[7]*1.25 (or *0.75 depending on the result of 1.1)
     1085
     1086    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1087    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1088
     1089    PAR[PM_PAR_7] = parStart[7];
     1090    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1091      if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1092    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1093    psVectorAppend (chi2, model->chisqNorm);
     1094
     1095    float fI = 1.1;
     1096    PAR[PM_PAR_7] = parStart[7]*fI;
     1097    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1098      if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1099    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1100    psVectorAppend (chi2, model->chisqNorm);
     1101
     1102    if (chi2->data.F32[1] < chi2->data.F32[0]) {
     1103      fI = 1.3;
     1104    } else {
     1105      fI = 1.0 / 1.3;
     1106    }
     1107   
     1108    PAR[PM_PAR_7] = parStart[7]*fI;
     1109    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1110      if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1111    psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1112    psVectorAppend (chi2, model->chisqNorm);
     1113
     1114    // can we fit the 3 pts with a parabola?
     1115    int nTry = 0;
     1116    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1117    while (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1118      psErrorClear (); // clear the polynomial error
     1119      if (nTry > 4) {
     1120        psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1121        psFree (chi2);
     1122        psFree (Sidx);
     1123        psFree (poly);
     1124        return false;
     1125      }
     1126      fI = (fI < 1.0) ? fI / 1.3 : fI * 1.3;
     1127      PAR[PM_PAR_7] = parStart[7]*fI;
     1128      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1129      if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1130      psVectorAppend (Sidx, 100*PAR[PM_PAR_7]);
     1131      psVectorAppend (chi2, model->chisqNorm);
     1132      nTry ++;
     1133    }
     1134
     1135    // where is the minimum of this polynomial fit?
     1136    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0;
     1137
     1138    // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
     1139    Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1140    PAR[PM_PAR_7] = Smin;
     1141
     1142    // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1143    // if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1144   
     1145    //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i];
     1146    ////
     1147    //// for (float fI = 0.0; fI < 0.15; fI += 0.01) {
     1148    ////   PAR[PM_PAR_7] = parStart[7] - fI;
     1149    ////
     1150    ////   // fit EXT (not PSF) model (set/unset the pixel mask)
     1151    ////   
     1152    ////   pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1153    ////   if (TIMING) {
     1154    ////        float *PAR = model->params->data.F32;
     1155    ////        fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]);
     1156    ////   }
     1157    //// }
     1158
     1159    // return to the original fitting mode (fitOptions)
     1160    pmPCMupdate(pcm, source, fitOptions, model);
     1161
     1162    psFree (chi2);
     1163    psFree (Sidx);
     1164    psFree (poly);
     1165
     1166    return true;
     1167}
     1168
     1169 
     1170// we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX
     1171bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
     1172
     1173    pmModel *model = pcm->modelConv;
     1174
     1175    assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));
     1176
     1177    pmSourceFitOptions options = *fitOptions;
     1178   
     1179    psF32 *PAR = pcm->modelConv->params->data.F32;
     1180
     1181    options.mode = PM_SOURCE_FIT_SHAPE;
     1182    options.nIter = 10;
     1183   
     1184    // update the pcm elements if we have changed the circumstance (here, options.mode)
     1185    pmPCMupdate(pcm, source, &options, model);
     1186   
     1187    psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32);
     1188    psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32);
     1189
     1190    float par7[] = {0.100, 0.125, 0.150, 0.175, 0.200, 0.225, 0.250};
     1191    for (int i = 0; i < 7; i++) {
     1192      PAR[PM_PAR_7] = par7[i];
     1193      pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1194      if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1195      psVectorAppend (Sidx, PAR[PM_PAR_7]);
     1196      psVectorAppend (chi2, model->chisqNorm);
     1197    }
     1198
     1199    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
     1200    if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) {
     1201      psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola");
     1202      psFree (chi2);
     1203      psFree (Sidx);
     1204      psFree (poly);
     1205      return false;
     1206    }
     1207
     1208    // where is the minimum of this polynomial fit?
     1209    fprintf (stderr, "fit1d: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1210    float Smin = -0.5 * poly->coeff[1] / poly->coeff[2];
     1211
     1212    // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev)
     1213    Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1);
     1214    PAR[PM_PAR_7] = Smin;
     1215    pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1216    if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]);
     1217   
     1218    //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i];
     1219    ////
     1220    //// for (float fI = 0.0; fI < 0.15; fI += 0.01) {
     1221    ////   PAR[PM_PAR_7] = parStart[7] - fI;
     1222    ////
     1223    ////   // fit EXT (not PSF) model (set/unset the pixel mask)
     1224    ////   
     1225    ////   pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);
     1226    ////   if (TIMING) {
     1227    ////        float *PAR = model->params->data.F32;
     1228    ////        fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]);
     1229    ////   }
     1230    //// }
     1231
     1232    // return to the original fitting mode (fitOptions)
     1233    pmPCMupdate(pcm, source, fitOptions, model);
     1234
     1235    psFree (chi2);
     1236    psFree (Sidx);
     1237    psFree (poly);
     1238
     1239    return true;
     1240}
     1241
     1242 
  • trunk/psphot/src/psphotStackImageLoop.c

Note: See TracChangeset for help on using the changeset viewer.