IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36828


Ignore:
Timestamp:
Jun 7, 2014, 5:38:26 AM (12 years ago)
Author:
eugene
Message:

merge changes from trunk

Location:
branches/eam_branches/ipp-20140423/psphot/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20140423/psphot/src

  • branches/eam_branches/ipp-20140423/psphot/src/psphot.h

    r36623 r36828  
    432432
    433433typedef struct {
    434     float fRmajorMin;
    435     float fRmajorMax;
    436     float fRmajorDel;
    437     float fRminorMin;
    438     float fRminorMax;
    439     float fRminorDel;
     434    float   Q;
     435    float   NSigma;
     436    float   clampSN;
     437    int     extModelType;
    440438} psphotGalaxyShapeOptions;
    441439
     
    537535bool psphotGalaxyShape_Threaded (psThreadJob *job);
    538536bool psphotGalaxyShapeGrid (pmSource *source, pmSourceFitOptions *fitOptions, psphotGalaxyShapeOptions *opt, psImageMaskType maskVal, int psfSize);
    539 bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, int psfSize, bool saveResults);
     537bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, pmSourceGalaxyFits *galaxyFits, psImageMaskType maskVal, int psfSize, bool saveResults);
    540538psphotGalaxyShapeOptions *psphotGalaxyShapeOptionsAlloc();
     539bool psphotGalaxyShapeOptionsSet(pmSource *source, pmSourceGalaxyFits *galaxyFits, psphotGalaxyShapeOptions *defaultOptions);
    541540
    542541bool psphotRadialProfileWings (pmConfig *config, const pmFPAview *view, const char *filerule);
  • branches/eam_branches/ipp-20140423/psphot/src/psphotFullForceSummary.c

    r36666 r36828  
    186186    psFitsClose(fits);
    187187
    188     // Convert to an array indexed by ID
    189     psArray *sortedTable = psArrayAlloc(4*inTable->n);
     188    // Convert to a set of arrays indexed by model type + 1
     189    // which contain pointers to arrays indexed by ID
     190#define MAX_MODEL_TYPE 10
     191    psArray *sortedTables = psArrayAlloc(MAX_MODEL_TYPE+1);
    190192    for (int i=0; i<inTable->n; i++) {
    191193        psMetadata *row = inTable->data[i];
    192194        psS32 ID = psMetadataLookupS32(&status, row, "ID");
     195        psS32 modelType = psMetadataLookupS32(&status, row, "MODEL_TYPE");
     196        // XXX: need to use the lookup table functions to be ready for changes in the model type numbers
     197        if (modelType+1 >= MAX_MODEL_TYPE) {
     198            psError(PSPHOT_ERR_CONFIG, false, "found modelType %d max allowed is %d", modelType, MAX_MODEL_TYPE);
     199            return false;
     200        }
     201        psArray *sortedTable = sortedTables->data[modelType+1];
     202        if (!sortedTable) {
     203            sortedTable = psArrayAlloc(4*inTable->n);
     204            sortedTables->data[modelType+1] = sortedTable;
     205            // dont' free sortedTable the array of tables gets our reference
     206        }
    193207        if (ID >= sortedTable->n) {
    194208            sortedTable = psArrayRealloc(sortedTable, 2*ID);
    195209            // Why doesn't psArrayRealloc do this?????
    196             sortedTable->n = sortedTable->nalloc;
     210                sortedTable->n = sortedTable->nalloc;
    197211        }
    198212        if (sortedTable->data[ID]) {
     
    202216        sortedTable->data[ID] = psMemIncrRefCounter(row);
    203217    }
    204     psMetadataAddArray(config->arguments, PS_LIST_TAIL, "CFF_TABLE", PS_META_REPLACE, "cff table", sortedTable);
     218    psMetadataAddArray(config->arguments, PS_LIST_TAIL, "CFF_TABLES", PS_META_REPLACE, "cff tables", sortedTables);
    205219    psFree(inTable);
    206     psFree(sortedTable);
     220    psFree(sortedTables);
    207221
    208222    return true;
  • branches/eam_branches/ipp-20140423/psphot/src/psphotFullForceSummaryReadout.c

    r36664 r36828  
    33
    44typedef struct {
     5    psF32   Q;
     6    psF32   NSigma;
     7    psF32   clampSN;
     8#ifdef notdef
     9    // these are per object now
    510    int     numTrials;
    6     psF32   fRmajorMin;
    7     psF32   fRmajorMax;
    8     psF32   fRmajorDel;
    9     psF32   fRminorMin;
    10     psF32   fRminorMax;
    11     psF32   fRminorDel;
    12     psVector    *rMajor;
    13     psVector    *rMinor;
    14     psArray *zeroPt;
    15     psArray *exptime;
    16     psArray *cffTable;
    17 } galaxyShapeOptions;
    18 
    19 static pmSource *psphotFullForceSummarizeObject(pmConfig *config, pmPhotObj *obj, psVector *fluxScaleFactor, galaxyShapeOptions *options);
     11    psF64   fRmajorMin;
     12    psF64   fRmajorMax;
     13    psF64   fRmajorDel;
     14    psF64   fRminorMin;
     15    psF64   fRminorMax;
     16    psF64   fRminorDel;
     17    psVector    *fRmajor;
     18    psVector    *fRminor;
     19#endif
     20    psArray *zeroPt;    // zero points for each input used with exptime to scale flux
     21    psArray *exptime;   // exposure times for each input
     22    psArray *cffTables; // one for each model type index is (model_type + 1) entry 0 is no extended model (star)
     23} galaxyShapeSummaryOptions;
     24
     25
     26
     27static pmSource *psphotFullForceSummarizeObject(pmConfig *config, pmPhotObj *obj, psVector *fluxScaleFactor, galaxyShapeSummaryOptions *options);
    2028static pmPhotObj *findObjectForSource(psArray **pObjects, pmSource *source);
    2129
    22 static bool setOptions(galaxyShapeOptions *options, pmReadout *readout, psMetadata *recipe, bool saveVectors);
    23 static bool checkOptions(galaxyShapeOptions *options, pmReadout *readout, psMetadata *recipe);
     30static bool setOptions(galaxyShapeSummaryOptions *options, pmReadout *readout, psMetadata *recipe, bool saveVectors);
     31static bool checkOptions(galaxyShapeSummaryOptions *options, pmReadout *readout, psMetadata *recipe);
    2432
    2533
     
    4755    psMetadataAddF32(outputCell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE, "Exposure time (sec)",
    4856        outputExptime);
    49     // don't think this one matters
    50 //    psMetadataAddF32(output->fpa->concepts, PS_LIST_TAIL, "FPA.EXPOSURE", PS_META_REPLACE, "Exposure time (sec)",
    51  //       outputExptime);
    5257
    5358    // Create objects from the various input's sources
    5459    // loop over the available readouts
    55 //    psArray *readouts = psArrayAlloc(num);
     60
    5661    psVector *fluxScaleFactor = psVectorAlloc(num, PS_TYPE_F32);
    57     galaxyShapeOptions options;
     62    galaxyShapeSummaryOptions options;
    5863    psArray *objects = NULL;
    5964    for (int index = 0; index < num; index++) {
     
    7277                return false;
    7378            }
    74             options.cffTable = psMetadataLookupPtr(NULL, config->arguments, "CFF_TABLE");
    75             if (!options.cffTable) {
     79            options.cffTables = psMetadataLookupPtr(NULL, config->arguments, "CFF_TABLES");
     80            if (!options.cffTables) {
    7681                psError (PS_ERR_UNKNOWN, true, "Cannot find cff table in arguments.");
    7782                return false;
     
    9196        psF32 scaleFactor = pow(10, 0.4 * (outputZeroPoint - zero_point)) * outputExptime / exptime;
    9297        fluxScaleFactor->data.F32[index] = scaleFactor;
    93 
    94 //        readouts->data[index] = readout;
    9598
    9699        // find detections
     
    177180}
    178181
    179 static pmSource *psphotFullForceSummarizeObject(pmConfig *config, pmPhotObj *obj, psVector *fluxScaleFactor, galaxyShapeOptions *options) {
     182static pmSource *psphotFullForceSummarizeObject(pmConfig *config, pmPhotObj *obj, psVector *fluxScaleFactor, galaxyShapeSummaryOptions *options) {
    180183
    181184    pmSource *outSrc = NULL;
    182185
    183     psVector *sumWeightedFlux = NULL;
    184     psVector *sumInvSig2 = NULL;
    185     psVector *numerator   = NULL;
    186 //    psVector *tmp = NULL;
    187     psF32   totalNPix = 0;
    188     long    vectorLength = 0;
    189 
     186
     187    pmSource *source0 = obj->sources->data[0];
     188    int ID = source0->seq;
     189
     190    // Find the parameters from the cff tables. nModels is the number of extended model types that
     191    // this source has an entry for
     192    int nModels = 0;
     193    // skip table 0 which is modelType -1 not extended
     194    for (int i=1; i<options->cffTables->n; i++) {
     195        psArray *table = options->cffTables->data[i];
     196        if (!table) continue;
     197        if (ID >= table->n) continue;
     198        if (table->data[ID]) {
     199            nModels++;
     200        }
     201    }
     202
     203    // Loop over sources for this object. Start output source for first input that has
     204    // good pixel frac
    190205    for (int i=0; i < obj->sources->n; i++) {
    191206        pmSource *source = obj->sources->data[i];
     
    212227                outSrc->extpars =  psMemIncrRefCounter(source->extpars);
    213228            }
    214             if (source->modelEXT) {
    215                 outSrc->modelEXT =  psMemIncrRefCounter(source->modelEXT);
    216             }
    217             if (source->modelFits) {
    218                 outSrc->modelFits =  psMemIncrRefCounter(source->modelFits);
    219             }
    220         }
    221 
    222         if (source->galaxyFits && isfinite(source->galaxyFits->nPix) && source->galaxyFits->chisq->n) {
    223             if (numerator == NULL) {
    224                 vectorLength = source->galaxyFits->chisq->n;
    225                 // tmp = psVectorAlloc(vectorLength, PS_TYPE_F32);
    226                 sumWeightedFlux = psVectorAlloc(vectorLength, PS_TYPE_F32);
    227                 psVectorInit(sumWeightedFlux, 0.0);
    228                 sumInvSig2 = psVectorAlloc(vectorLength, PS_TYPE_F32);
    229                 psVectorInit(sumInvSig2, 0.0);
    230                 numerator   = psVectorAlloc(vectorLength, PS_TYPE_F32);
    231                 psVectorInit(numerator, 0.0);
    232             }
    233 
    234             psAssert(vectorLength == options->numTrials, "length of chisq vector %ld does not match options %d",
    235                 vectorLength, options->numTrials);
    236             psAssert(source->galaxyFits->chisq->n == vectorLength, "length of chisq vectors do not match %ld %ld",
    237                     source->galaxyFits->chisq->n, vectorLength);
    238 
    239 
    240             psF32 scaleFactor = fluxScaleFactor->data.F32[source->imageID];
     229        }
     230        if (nModels && source->modelFits && source->modelFits->n) {
     231            if (!outSrc->modelFits) {
     232                outSrc->modelFits = psArrayAllocEmpty(nModels);
     233            }
     234            for (int iModel = 0; iModel < source->modelFits->n; iModel++) {
     235                pmModel *newModel = source->modelFits->data[iModel];
     236                pmModel *outModel = NULL;
     237                for (int jModel = 0; jModel < outSrc->modelFits->n; jModel++) {
     238                    outModel = outSrc->modelFits->data[jModel];
     239                    if (newModel->type == outModel->type)  {
     240                        // already have an entry for this type
     241                        break;
     242                    }
     243                    outModel = NULL;
     244                }
     245                if (!outModel) {
     246                    // no model of this type in output source yet. Add this one.
     247                    // Note: the parameters that we need (position, angle, index, if applicable)
     248                    // are the same for all sources so copying any of them is fine
     249                    psArrayAdd(outSrc->modelFits, 1, newModel);
     250                }
     251            }
     252        }
     253    }
     254
     255    if (!outSrc) {
     256        // no good measurements for this source (how?)
     257        return NULL;
     258    }
     259
     260    // now loop over the model fits and summarize the galaxy shape measurements for each
     261    for (int iModel=0; outSrc->modelFits && iModel < outSrc->modelFits->n; iModel++) {
     262        pmModel *model = outSrc->modelFits->data[iModel];
     263        int modelType = model->type;
     264        psAssert(modelType >= 0 && modelType+1 < options->cffTables->n, "model type out of range");
     265
     266        psArray *cffTable = options->cffTables->data[modelType+1];
     267        psAssert(cffTable, "missing cff table?");
     268
     269        psMetadata *cffRow = cffTable->data[outSrc->seq];
     270        if (!cffRow) {
     271            psError (PS_ERR_PROGRAMMING, true, "NO cff data for object %d model %d", outSrc->seq, modelType);
     272            psFree(outSrc);
     273            return NULL;
     274        }
     275        bool mdok;
     276        psF32 R_MAJOR = psMetadataLookupF32(&mdok, cffRow, "R_MAJOR");
     277        if (!mdok) {
     278            psError (PS_ERR_PROGRAMMING, true, "can't find R_MAJOR for object %d type %d", outSrc->seq, modelType);
     279            psFree(outSrc);
     280            return NULL;
     281        }
     282        psF32 R_MINOR = psMetadataLookupF32(&mdok, cffRow, "R_MINOR");
     283        if (!mdok) {
     284            psError (PS_ERR_PROGRAMMING, true, "can't find R_MINOR for object %d type %d", outSrc->seq, modelType);
     285            psFree(outSrc);
     286            return NULL;
     287        }
     288
     289        psVector *sumWeightedFlux = NULL;
     290        psVector *sumInvSig2 = NULL;
     291        psVector *numerator   = NULL;
     292        psVector *fRmajorVec = NULL;
     293        psVector *fRminorVec = NULL;
     294        psF32   totalNPix = 0;
     295        long    vectorLength = 0;
     296        psF32   fRmajorMin = 0;
     297        psF32   fRmajorMax = 0;
     298        psF32   fRmajorDel = 0;
     299        psF32   fRminorMin = 0;
     300        psF32   fRminorMax = 0;
     301        psF32   fRminorDel = 0;
     302        for (int i=0; i < obj->sources->n; i++) {
     303            pmSource *source = obj->sources->data[i];
     304
     305            if (source->pixWeightNotPoor < .9) continue;
     306
     307            // The only parameters that we are summarizing currently are galaxy shapes.
     308            if (!source->modelFits) continue;
     309            if (!source->galaxyFits) continue;
     310
     311            // XXX: put this into a function
     312            pmSourceGalaxyFits *galaxyFits = NULL;
     313            for (int j=0; j<source->galaxyFits->n; j++) {
     314                galaxyFits = source->galaxyFits->data[j];
     315                if (galaxyFits && galaxyFits->modelType == modelType) break;
     316                galaxyFits = NULL;
     317            }
     318
     319            if (galaxyFits && isfinite(galaxyFits->nPix) && galaxyFits->chisq->n) {
     320                if (numerator == NULL) {
     321                    // first source with galaxyFits allocate accumulators
     322                    vectorLength = galaxyFits->chisq->n;
     323                    sumWeightedFlux = psVectorAlloc(vectorLength, PS_TYPE_F32);
     324                    psVectorInit(sumWeightedFlux, 0.0);
     325                    sumInvSig2 = psVectorAlloc(vectorLength, PS_TYPE_F32);
     326                    psVectorInit(sumInvSig2, 0.0);
     327                    numerator   = psVectorAlloc(vectorLength, PS_TYPE_F32);
     328                    psVectorInit(numerator, 0.0);
     329
     330                    // Initialize the fractional radius vectors
     331                    // save these to initialize the output galaxy fits
     332                    fRmajorMin = galaxyFits->fRmajorMin;
     333                    fRmajorMax = galaxyFits->fRmajorMax;
     334                    fRmajorDel = galaxyFits->fRmajorDel;
     335                    fRminorMin = galaxyFits->fRminorMin;
     336                    fRminorMax = galaxyFits->fRminorMax;
     337                    fRminorDel = galaxyFits->fRminorDel;
     338                    fRmajorVec = psVectorAlloc(vectorLength, PS_TYPE_F32);
     339                    fRminorVec = psVectorAlloc(vectorLength, PS_TYPE_F32);
     340                    int k = 0;
     341                    for (float fRmajor = fRmajorMin; fRmajor < fRmajorMax + 0.5*fRmajorDel; fRmajor += fRmajorDel) {
     342                        for (float fRminor = fRminorMin; fRminor < fRminorMax + 0.5*fRminorDel; fRminor += fRminorDel) {
     343                            fRminorVec->data.F32[k] = fRminor;
     344                            fRmajorVec->data.F32[k] = fRmajor;
     345                            k++;
     346                        }
     347                    }
     348                    psAssert(k == vectorLength, "mismatched vectors");
     349                }
     350
     351                // Die if the lengths of the vectors is not the same in all sources
     352#ifdef notdef
     353                psAssert(vectorLength == options->numTrials, "length of chisq vector %ld does not match options %d",
     354                    vectorLength, options->numTrials);
     355#endif
     356                psAssert(galaxyFits->chisq->n == vectorLength, "length of chisq vectors do not match %ld %ld",
     357                             galaxyFits->chisq->n, vectorLength);
     358
     359                psF32 scaleFactor = fluxScaleFactor->data.F32[source->imageID];
     360
     361                totalNPix += galaxyFits->nPix;
     362
     363                for (int k = 0; k < vectorLength; k++) {
     364                    psF32 chisq = galaxyFits->chisq->data.F32[k];
     365                    psF32 flux  = galaxyFits->Flux->data.F32[k]  * scaleFactor;
     366                    psF32 dFlux = galaxyFits->dFlux->data.F32[k] * scaleFactor;
     367
     368                    numerator->data.F32[k] += chisq * galaxyFits->nPix;
     369
     370                    psF32 invSig2 = 1.0 / (dFlux * dFlux);
     371                    sumInvSig2->data.F32[k] += invSig2;
     372
     373                    sumWeightedFlux->data.F32[k] += flux * invSig2;
     374                }
     375            }
     376        }
     377
     378        if (vectorLength) {
     379            // allocate galaxyFits for the output source
     380            if (!outSrc->galaxyFits) {
     381                outSrc->galaxyFits = psArrayAllocEmpty(1);
     382            }
     383            pmSourceGalaxyFits *galaxyFits = pmSourceGalaxyFitsAlloc();
     384            psArrayAdd(outSrc->galaxyFits, 1, galaxyFits);
     385            psFree(galaxyFits);
     386
     387            galaxyFits->nPix  = totalNPix;
     388            galaxyFits->modelType = modelType;
     389            psVector *fluxVec =
     390                galaxyFits->Flux  = psVectorRecycle(galaxyFits->Flux,  vectorLength, PS_TYPE_F32);
     391            psVector *dFluxVec =
     392                galaxyFits->dFlux = psVectorRecycle(galaxyFits->dFlux, vectorLength, PS_TYPE_F32);
     393            psVector *chisqVec =
     394                galaxyFits->chisq = psVectorRecycle(galaxyFits->chisq, vectorLength, PS_TYPE_F32);
     395
     396            galaxyFits->fRmajorMin = fRmajorMin;
     397            galaxyFits->fRmajorMax = fRmajorMax;
     398            galaxyFits->fRmajorDel = fRmajorDel;
     399            galaxyFits->fRminorMin = fRminorMin;
     400            galaxyFits->fRminorMax = fRminorMax;
     401            galaxyFits->fRminorDel = fRminorDel;
     402
     403            // fill the summary galaxyFits vectors and find the trial with the minimum value for chisq
     404
     405            int min_k = -1;
     406            psF32 minChisq = NAN;
    241407
    242408            for (int k = 0; k < vectorLength; k++) {
    243 
    244                 psF32 chisq = source->galaxyFits->chisq->data.F32[k];
    245                 psF32 flux  = source->galaxyFits->Flux->data.F32[k]  * scaleFactor;
    246                 psF32 dFlux = source->galaxyFits->dFlux->data.F32[k] * scaleFactor;
    247                 // for chisq
    248                 // Numerator = sum( nPix[i] * chisq[i] )
    249                 // denominator will be sum( nPix )
    250 
    251 
    252 //                tmp = (psVector *) psBinaryOp(tmp,
    253  //                   source->galaxyFits->chisq, "*", psScalarAlloc(source->galaxyFits->nPix, PS_TYPE_F32));
    254 //                numerator = (psVector *) psBinaryOp(numerator, numerator, "+", tmp);
    255 
    256                 numerator->data.F32[k] += chisq * source->galaxyFits->nPix;
    257                 totalNPix += source->galaxyFits->nPix;
    258 
    259                 // sumInvSig2 = sum( 1 / dFlux**2 )
    260 //                tmp = (psVector *) psBinaryOp(tmp, source->galaxyFits->dFlux, "*", source->galaxyFits->dFlux);
    261 //                tmp = (psVector *) psBinaryOp(tmp, psScalarAlloc(1.0, PS_TYPE_F32), "/", tmp);
    262 //                sumInvSig2 = (psVector *) psBinaryOp(sumInvSig2, sumInvSig2, "+", tmp);
    263 //
    264                 psF32 invSig2 = 1.0 / (dFlux * dFlux);
    265                 sumInvSig2->data.F32[k] += invSig2;
    266 
    267                 // sumWeightedFlux = sum ( Flux / dFlux**2 )
    268 //                tmp = (psVector *) psBinaryOp(tmp, source->galaxyFits->Flux, "*", tmp);
    269 //                sumWeightedFlux = (psVector *) psBinaryOp(sumWeightedFlux, sumWeightedFlux, "+", tmp);
    270                 sumWeightedFlux->data.F32[k] += flux * invSig2;
    271             }
    272         }
    273     }
    274 
    275     if (outSrc) {
    276         if (vectorLength) {
    277             outSrc->galaxyFits = pmSourceGalaxyFitsAlloc();
    278             outSrc->galaxyFits->nPix = totalNPix;
    279             outSrc->galaxyFits->Flux  = psVectorRecycle(outSrc->galaxyFits->Flux, vectorLength, PS_TYPE_F32);
    280             outSrc->galaxyFits->dFlux = psVectorRecycle(outSrc->galaxyFits->dFlux, vectorLength, PS_TYPE_F32);
    281             outSrc->galaxyFits->chisq = psVectorRecycle(outSrc->galaxyFits->chisq, vectorLength, PS_TYPE_F32);
    282             for (int k = 0; k < vectorLength; k++) {
    283                 outSrc->galaxyFits->Flux->data.F32[k]  = sumWeightedFlux->data.F32[k] / sumInvSig2->data.F32[k];
    284                 outSrc->galaxyFits->dFlux->data.F32[k] = 1.0 / sumInvSig2->data.F32[k];
    285                 outSrc->galaxyFits->chisq->data.F32[k] = numerator->data.F32[k] / totalNPix;
    286 
    287 #ifdef nodef
    288                 outSrc->galaxyFits->Flux = (psVector *) psBinaryOp(outSrc->galaxyFits->Flux,
    289                         sumWeightedFlux, "/", sumInvSig2);
    290 
    291                 outSrc->galaxyFits->dFlux = (psVector *) psBinaryOp(outSrc->galaxyFits->dFlux,
    292                         psScalarAlloc(1.0, PS_TYPE_F32), "/", sumInvSig2);
    293 
    294                 outSrc->galaxyFits->chisq = (psVector *) psBinaryOp(outSrc->galaxyFits->chisq,
    295                         numerator, "/", psScalarAlloc(totalNPix, PS_TYPE_F32));
    296 #endif
     409                fluxVec->data.F32[k]  = sumWeightedFlux->data.F32[k] / sumInvSig2->data.F32[k];
     410                dFluxVec->data.F32[k] = 1.0 / sumInvSig2->data.F32[k];
     411
     412                psF32 thischisq = chisqVec->data.F32[k] = numerator->data.F32[k] / totalNPix;
     413
     414                if (isfinite(thischisq)  && (!isfinite(minChisq) || thischisq < minChisq)) {
     415                    min_k = k;
     416                    minChisq = thischisq;
     417                }
    297418            }
    298419
     
    300421            psFree(sumInvSig2);
    301422            psFree(sumWeightedFlux);
    302 //            psFree(tmp);
    303 
    304             int min_j = -1;
    305             psF32 minChisq = NAN;
    306             psVector *chisq = outSrc->galaxyFits->chisq;
    307             for (int j=0; j < chisq->n; j++) {
    308                 psF32 thischisq = chisq->data.F32[j];
    309                 if (isfinite(thischisq)  && (!isfinite(minChisq) || thischisq < minChisq)) {
    310                     min_j = j;
    311                     minChisq = thischisq;
     423
     424            if (min_k >= 0 && isfinite(minChisq)) {
     425                // copy the best fit params to the model
     426                // fractional radii with the lowest chisq
     427                psEllipseAxes axes = pmPSF_ModelToAxes(model->params->data.F32, model->type);
     428
     429                // examine the params for the trial with minimum chisq.
     430                bool fitMajor = true;
     431                bool fitMinor = true;
     432                psF64 fRmajorBest = fRmajorVec->data.F32[min_k];
     433                if ((fabs(fRmajorBest - galaxyFits->fRmajorMin) < galaxyFits->fRmajorDel) ||
     434                    (fabs(fRmajorBest - galaxyFits->fRmajorMax) < galaxyFits->fRmajorDel)) {
     435                    fitMajor = false;
    312436                }
    313             }
    314             if (min_j >= 0 && isfinite(minChisq) && outSrc->modelEXT) {
    315                 // copy the best fit params to the model
    316                 psEllipseAxes axes = pmPSF_ModelToAxes(outSrc->modelEXT->params->data.F32, outSrc->modelEXT->type);
    317                 if (outSrc->seq >= options->cffTable->n) {
    318                     psError(PS_ERR_PROGRAMMING, true, "object sequence number %d is larger than cff table length %ld",
    319                         outSrc->seq, options->cffTable->n);
    320                     return NULL;
     437                psF64 fRminorBest = fRminorVec->data.F32[min_k];
     438                if ((fabs(fRminorBest - galaxyFits->fRminorMin) < galaxyFits->fRminorDel) ||
     439                    (fabs(fRminorBest - galaxyFits->fRminorMax) < galaxyFits->fRminorDel)) {
     440                    fitMinor = false;
    321441                }
    322                 psMetadata *row = options->cffTable->data[outSrc->seq];
    323                 if (!row) {
    324                     psError (PS_ERR_PROGRAMMING, true, "NO cff data for object %d", outSrc->seq);
    325                     psFree(outSrc);
    326                     return NULL;
     442                // If either major or minor is at one of the limits do not fit report the minimum value
     443                bool useFit = fitMajor && fitMinor;
     444
     445                // save the flux and dFlux values from entry with lowest chisq
     446                psF64 fluxBest = fluxVec->data.F32[min_k];
     447                psF64 dFluxBest = dFluxVec->data.F32[min_k];
     448                psF64 dFlux0   = NAN;
     449                psF64 flux0    = NAN;
     450
     451                if (useFit) {
     452                    #define NUM_TRIALS_INIT 9
     453                    psVector *major = psVectorAllocEmpty(NUM_TRIALS_INIT, PS_TYPE_F64);
     454                    psVector *minor = psVectorAllocEmpty(NUM_TRIALS_INIT, PS_TYPE_F64);
     455                    psVector *chisq = psVectorAllocEmpty(NUM_TRIALS_INIT, PS_TYPE_F64);
     456                    psVector *flux = psVectorAllocEmpty(NUM_TRIALS_INIT, PS_TYPE_F64);
     457                    psVector *dFlux = psVectorAllocEmpty(NUM_TRIALS_INIT, PS_TYPE_F64);
     458
     459                    // XXX: use a recipe parameter instead of 2.2
     460                    psF64 maxDeltaMaj = 2.2 * galaxyFits->fRmajorDel;
     461                    psF64 maxDeltaMin = 2.2 * galaxyFits->fRminorDel;
     462
     463                    psF64 majorMin = NAN;
     464                    psF64 majorMax = NAN;
     465                    psF64 minorMin = NAN;
     466                    psF64 minorMax = NAN;
     467                    psF64 chisqMin = NAN;
     468                    psF64 chisqMax = NAN;
     469                    for (int k = 0; k < vectorLength; k++) {
     470
     471                        if (fabs(fRmajorVec->data.F32[k] - fRmajorBest) < maxDeltaMaj &&
     472                            fabs(fRminorVec->data.F32[k] - fRminorBest) < maxDeltaMin) {
     473
     474                            if (isfinite(chisqVec->data.F32[k]) &&
     475                                isfinite(fluxVec->data.F32[k])  &&
     476                                isfinite(dFluxVec->data.F32[k])) {
     477
     478                                // compute major and minor radius vectors from nominal and trial fractions
     479                                // also find the ranges in the vectors
     480                                psF64 thisMajor = R_MAJOR * fRmajorVec->data.F32[k];
     481                                if (!isfinite(majorMin) || thisMajor < majorMin) {
     482                                    majorMin = thisMajor;
     483                                }
     484                                if (!isfinite(majorMax) || thisMajor > majorMax) {
     485                                    majorMax = thisMajor;
     486                                }
     487                                psVectorAppend(major, thisMajor);
     488
     489                                psF64 thisMinor = R_MINOR * fRminorVec->data.F32[k];
     490                                if (!isfinite(minorMin) || thisMinor < minorMin) {
     491                                    minorMin = thisMinor;
     492                                }
     493                                if (!isfinite(minorMax) || thisMinor > minorMax) {
     494                                    minorMax = thisMinor;
     495                                }
     496                                psVectorAppend(minor, thisMinor);
     497
     498                                psF64 thisChisq = chisqVec->data.F32[k];
     499                                if (!isfinite(chisqMin) || thisChisq < chisqMin) {
     500                                    chisqMin = thisChisq;
     501                                }
     502                                if (!isfinite(chisqMax) || thisChisq > chisqMax) {
     503                                    chisqMax = thisChisq;
     504                                }
     505                                psVectorAppend(chisq, thisChisq);
     506
     507                                psVectorAppend(flux,  fluxVec->data.F32[k]);
     508                                psVectorAppend(dFlux, dFluxVec->data.F32[k]);
     509                            }
     510                        }
     511                    }
     512
     513
     514                    // see if we ever get too few good values (haven't seen this happen)
     515                    if (major->n < NUM_TRIALS_INIT) {
     516                        fprintf(stderr, "only found %ld good points wanted %d for seq: %d\n",
     517                            major->n, NUM_TRIALS_INIT, outSrc->seq);
     518                    }
     519
     520                    // rescale data - this helps avoid precision errors.
     521                    psF64 majorRange = majorMax - majorMin;
     522                    if (majorRange == 0) {
     523                        majorRange = 1;
     524                    }
     525                    psF64 minorRange = minorMax - minorMin;
     526                    if (minorRange == 0) {
     527                        minorRange = 1;
     528                    }
     529                    psF64 chisqRange = chisqMax - chisqMin;
     530                    if (chisqRange == 0) {
     531                        chisqRange = 1;
     532                    }
     533                    for (int k = 0; k < major->n; k++) {
     534                        major->data.F64[k] = (major->data.F64[k] - majorMin) / majorRange;
     535                        minor->data.F64[k] = (minor->data.F64[k] - minorMin) / minorRange;
     536                        chisq->data.F64[k] = (chisq->data.F64[k] - chisqMin) / chisqRange;
     537                    }
     538
     539                    // Fit chisq versus rMajor and rMinor
     540                    psPolynomial2D *chisqFit = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 2, 2);
     541                    psPolynomial2D *fluxFit = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 2, 2);
     542                    psPolynomial2D *fluxErrorFit = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 2, 2);
     543                    chisqFit->coeffMask[2][2] = PS_POLY_MASK_SET;
     544                    chisqFit->coeffMask[2][1] = PS_POLY_MASK_SET;
     545                    chisqFit->coeffMask[1][2] = PS_POLY_MASK_SET;
     546                    fluxFit->coeffMask[2][2] = PS_POLY_MASK_SET;
     547                    fluxFit->coeffMask[2][1] = PS_POLY_MASK_SET;
     548                    fluxFit->coeffMask[1][2] = PS_POLY_MASK_SET;
     549                    fluxErrorFit->coeffMask[2][2] = PS_POLY_MASK_SET;
     550                    fluxErrorFit->coeffMask[2][1] = PS_POLY_MASK_SET;
     551                    fluxErrorFit->coeffMask[1][2] = PS_POLY_MASK_SET;
     552
     553                    bool goodFit = psVectorFitPolynomial2D (chisqFit, NULL, 0xff, chisq, NULL, major, minor);
     554
     555                    if (goodFit) {
     556                        // find the axes for the minimum chisq from the formula
     557                        psF64 **coeff = chisqFit->coeff;
     558                        psF64 D = 4*coeff[2][0]*coeff[0][2] - coeff[1][1]*coeff[1][1];
     559                        psF64 major0 = ((coeff[1][1]*coeff[0][1] - 2*coeff[0][2]*coeff[1][0]) / D) * majorRange + majorMin;
     560                        psF64 minor0 = ((coeff[1][1]*coeff[1][0] - 2*coeff[2][0]*coeff[0][1]) / D) * minorRange + minorMin;
     561
     562                        // estimated chisq at the minimum
     563                        psF64 chisq0 = psPolynomial2DEval(chisqFit, major0, minor0) * chisqRange + chisqMin;
     564
     565                        // now fit the flux ...
     566                        bool goodFluxFit = psVectorFitPolynomial2D(fluxFit, NULL, 0xFF, flux, NULL, major, minor);
     567
     568                        // .. and compute flux at the minimum chisq position
     569                        if (goodFluxFit) {
     570                            flux0  = psPolynomial2DEval(fluxFit, major0, minor0);
     571                        } else {
     572                            flux0 = fluxBest;
     573                        }
     574
     575                        // .. and compute dFlux at the minimum chisq position
     576                        bool goodFluxErrorFit = psVectorFitPolynomial2D(fluxErrorFit, NULL, 0xFF, dFlux, NULL, major, minor);
     577                        if (goodFluxErrorFit) {
     578                            dFlux0  = psPolynomial2DEval(fluxErrorFit, major0, minor0);
     579                        } else {
     580                            dFlux0 = dFluxBest;
     581                        }
     582
     583#ifdef PRINTVALS
     584                        fprintf (stderr, "%4d %3d %3ld | %6.3f %6.3f %6.3f %4.2f |  %6.3f %6.3f %6.3f %4.2f | %7.4f %7.4f %7.1f %7.1f\n",
     585                            outSrc->seq, min_k, major->n, R_MAJOR, fRmajorBest*R_MAJOR, major0, major0/R_MAJOR, R_MINOR, fRminorBest*R_MINOR, minor0, minor0/R_MINOR, minChisq, chisq0, fluxBest, flux0);
     586#endif
     587
     588
     589                        axes.major = major0;
     590                        axes.minor = minor0;
     591                        model->chisq = chisq0;
     592#ifdef DUMPVECTORS
     593                        char fn[80];
     594
     595                        sprintf(fn, "vectors/%s.%05d.txt", goodFit ? "g" : "b", outSrc->seq);
     596
     597                        FILE *f = fopen(fn, "w");
     598                        fprintf(f, "#major minor chisq i\n");
     599                        for (int k = 0; k < chisq->n; k++) {
     600                            fprintf(f, "%10.6f %10.6f %10.6f %5d\n",
     601                                major->data.F64[k]/R_MAJOR, minor->data.F64[k]/R_MINOR, chisq->data.F64[k], k);
     602                        }
     603                        fclose(f);
     604#endif
     605                    } else {
     606                        model->flags |= PM_MODEL_STATUS_NONCONVERGE;
     607
     608#ifdef PRINTVALS
     609                        fprintf(stderr, "%4d %3d %3ld | %6.3f %6.3f %6.3f %6.3f bad fit\n",
     610                            outSrc->seq, min_k, major->n, R_MAJOR, fRmajorBest, R_MINOR, fRminorBest);
     611#endif
     612                        psErrorClear();
     613                        // psFree(outSrc->galaxyFits);
     614
     615                    }
     616                    psFree(chisqFit);
     617                    psFree(fluxFit);
     618                    psFree(fluxErrorFit);
     619                    psFree(major);
     620                    psFree(minor);
     621                    psFree(chisq);
     622                    psFree(flux);
     623                    psFree(dFlux);
     624                } else {
     625                    // No fit
     626                    // Set the values based on the trial with the best chisq
     627                    axes.major = R_MAJOR * fRmajorBest;
     628                    axes.minor = R_MINOR * fRminorBest;
     629                    model->chisq = minChisq;
     630                    flux0 = fluxBest;
     631                    dFlux0 = dFluxBest;
     632#ifdef PRINTVALS
     633                    fprintf(stderr, "%4d %3d %3ld | %6.3f %6.3f %6.3f %6.3f skip fit\n",
     634                            outSrc->seq, min_k, 0L, R_MAJOR, fRmajorBest, R_MINOR, fRminorBest);
     635#endif
    327636                }
    328                 bool mdok;
    329                 psF32 rMajor = psMetadataLookupF32(&mdok, row, "R_MAJOR");
    330                 if (!mdok) {
    331                     psError (PS_ERR_PROGRAMMING, true, "can't find R_MAJOR for object %d", outSrc->seq);
    332                     psFree(outSrc);
    333                     return NULL;
    334                 }
    335                 psF32 rMinor = psMetadataLookupF32(&mdok, row, "R_MINOR");
    336                 if (!mdok) {
    337                     psError (PS_ERR_PROGRAMMING, true, "can't find R_MINOR for object %d", outSrc->seq);
    338                     psFree(outSrc);
    339                     return NULL;
    340                 }
    341                 axes.major = rMajor * options->rMajor->data.F32[min_j];
    342                 axes.minor = rMinor * options->rMinor->data.F32[min_j];
    343                 pmPSF_AxesToModel (outSrc->modelEXT->params->data.F32, axes, outSrc->modelEXT->type);
    344                 outSrc->modelEXT->chisq = minChisq;
    345                 outSrc->modelEXT->mag = -2.5 * log10(outSrc->galaxyFits->Flux->data.F32[min_j]);
    346                 outSrc->modelEXT->magErr = 1.0 /
    347                     (outSrc->galaxyFits->Flux->data.F32[min_j]/outSrc->galaxyFits->dFlux->data.F32[min_j]); // 1 / SN
    348             }
    349         }
     637                // now save the model parameters in the model structure
     638
     639                pmPSF_AxesToModel (model->params->data.F32, axes, modelType);
     640
     641                model->mag = -2.5 * log10(flux0);
     642                model->magErr = dFlux0 / flux0; // 1 / SN
     643                // XXX: should there be a different flag if we didn't do a fit of the chisq
     644                model->flags |= PM_MODEL_STATUS_FITTED;
     645            }
     646        }
     647        psFree(fRminorVec);
     648        psFree(fRmajorVec);
    350649    }
    351650
     
    360659    }
    361660
    362 static bool setOptions(galaxyShapeOptions *opt, pmReadout *readout, psMetadata *recipe, bool makeVectors) {
     661static bool setOptions(galaxyShapeSummaryOptions *opt, pmReadout *readout, psMetadata *recipe, bool makeVectors) {
    363662    bool status;
    364     bool useAnalysis;
    365 
     663    bool useAnalysis;   // fall back to recipe if we dont' find values in analysis. Probably should no longer do this
     664
     665#ifdef notdef
    366666    psMetadataLookupF32(&useAnalysis, readout->analysis, "GALAXY_SHAPES_FR_MAJOR_MIN");
     667#endif
     668    psMetadataLookupF32(&useAnalysis, readout->analysis, "GALAXY_SHAPES_Q");
    367669    psMetadata *md = useAnalysis ? readout->analysis : recipe;
    368670
     671    GETVAL(Q, "GALAXY_SHAPES_Q");
     672    GETVAL(NSigma, "GALAXY_SHAPES_NSIGMA");
     673    GETVAL(clampSN, "GALAXY_SHAPES_CLAMP_SN");
     674
     675#ifdef notdef
     676    // these are per object now
    369677    GETVAL(fRmajorMin, "GALAXY_SHAPES_FR_MAJOR_MIN");
    370678    GETVAL(fRmajorMax, "GALAXY_SHAPES_FR_MAJOR_MAX");
     
    378686
    379687    if (makeVectors) {
    380         opt->rMinor = psVectorAlloc(opt->numTrials, PS_TYPE_F32);
    381         opt->rMajor = psVectorAlloc(opt->numTrials, PS_TYPE_F32);
     688        opt->fRminor = psVectorAlloc(opt->numTrials, PS_TYPE_F32);
     689        opt->fRmajor = psVectorAlloc(opt->numTrials, PS_TYPE_F32);
    382690        int i = 0;
    383691        for (float fRmajor = opt->fRmajorMin; fRmajor < opt->fRmajorMax + 0.5*opt->fRmajorDel;
     
    385693            for (float fRminor = opt->fRminorMin; fRminor < opt->fRminorMax + 0.5*opt->fRminorDel;
    386694                    fRminor += opt->fRminorDel) {
    387                 opt->rMinor->data.F32[i] = fRminor;
    388                 opt->rMajor->data.F32[i] = fRmajor;
     695                opt->fRminor->data.F32[i] = fRminor;
     696                opt->fRmajor->data.F32[i] = fRmajor;
    389697                i++;
    390698            }
     
    392700        psAssert(i == opt->numTrials, "Something's wrong with my loop got %d entries expected %d", i, opt->numTrials);
    393701    } else {
    394         opt->rMinor = NULL;
    395         opt->rMajor = NULL;
    396     }
     702        opt->fRminor = NULL;
     703        opt->fRmajor = NULL;
     704    }
     705#endif
    397706       
    398707    return true;
     
    405714    }
    406715
    407 static bool checkOptions(galaxyShapeOptions *options, pmReadout *readout, psMetadata *recipe) {
    408     galaxyShapeOptions thisReadoutsOptions;
     716static bool checkOptions(galaxyShapeSummaryOptions *options, pmReadout *readout, psMetadata *recipe) {
     717    galaxyShapeSummaryOptions thisReadoutsOptions;
    409718   
    410719    if (!setOptions(&thisReadoutsOptions, readout, recipe, false)) {
     
    412721        return false;
    413722    }
     723    CHECKVAL(options, thisReadoutsOptions, Q, "mismatched Q");
     724    CHECKVAL(options, thisReadoutsOptions, NSigma, "mismatched NSIGMA");
     725    CHECKVAL(options, thisReadoutsOptions, clampSN, "mismatched cleampSN");
     726
     727#ifdef notdef
     728    // these are per object now
    414729    CHECKVAL(options, thisReadoutsOptions, numTrials, "mismatched number of trials")
    415730    CHECKVAL(options, thisReadoutsOptions, fRmajorMin, "mismatched fRmajorMin")
     
    419734    CHECKVAL(options, thisReadoutsOptions, fRminorMax, "mismatched fRminorMax")
    420735    CHECKVAL(options, thisReadoutsOptions, fRminorDel, "mismatched fRminorDel")
     736#endif
    421737
    422738    return true;
  • branches/eam_branches/ipp-20140423/psphot/src/psphotGalaxyShape.c

    r36633 r36828  
    8080    assert (markVal);
    8181
    82     // maskVal is used to test for rejected pixels, and must include markVal
    8382    maskVal |= markVal;
    8483
    85     // bit-mask to mark pixels not used in analysis
    8684    psphotGalaxyShapeOptions *opt = psphotGalaxyShapeOptionsAlloc();
     85    opt->Q = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_Q");
     86    psAssert (status, "missing GALAXY_SHAPES_Q");
     87    opt->NSigma = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_NSIGMA");
     88    psAssert (status, "missing GALAXY_SHAPES_NSIGMA");
     89    opt->clampSN = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_CLAMP_SN");
     90    psAssert (status, "missing GALAXY_SHAPES_NSIGMA");
     91    psString modelTypeToSave = psMetadataLookupStr(&status, recipe, "EXT_MODEL_TYPE_FORCE");
     92    if (modelTypeToSave && strcmp(modelTypeToSave, "ALL") && strcmp(modelTypeToSave, "BEST")) {
     93        opt->extModelType = pmModelClassGetType(modelTypeToSave);
     94    } else {
     95        opt->extModelType = pmModelClassGetType("PS_MODEL_SERSIC");
     96    }
     97
     98#ifdef notdef
    8799    opt->fRmajorMin = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_FR_MAJOR_MIN"); if (!status) opt->fRmajorMin = 0.5;
    88100    opt->fRmajorMax = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_FR_MAJOR_MAX"); if (!status) opt->fRmajorMax = 2.0;
     
    91103    opt->fRminorMax = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_FR_MINOR_MAX"); if (!status) opt->fRminorMax = 2.0;
    92104    opt->fRminorDel = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_FR_MINOR_DEL"); if (!status) opt->fRminorDel = 0.1;
     105#endif
    93106
    94107    // what fraction of the PSF is used? (radius in pixels : 2 -> 5x5 box)
     
    238251bool psphotGalaxyShapeGrid (pmSource *source, pmSourceFitOptions *fitOptions, psphotGalaxyShapeOptions *opt, psImageMaskType maskVal, int psfSize) {
    239252
    240     // we use the 0th model to define the initial guess shape
    241     pmModel *model = source->modelFits->data[0];
    242     if (!model) return false;
    243 
    244     pmModelType modelType = model->type;
    245 
    246     // we are using fitOptions->mode : be sure this makes sense
    247     pmPCMdata *pcm = pmPCMinit (source, fitOptions, model, maskVal, psfSize);
    248     if (!pcm) return false;
    249 
    250     // we are fitting only PM_PAR_I0; the shape elements are generated from a grid
    251     psF32 *PAR = pcm->modelConv->params->data.F32;
    252 
    253     // double check that the guess is carried along...
    254 
    255     // I have some source guess (e0, e1, e2)
    256     psEllipseAxes guessAxes = pmPSF_ModelToAxes (PAR, modelType);
    257 
    258     if (!source->galaxyFits) {
    259         source->galaxyFits = pmSourceGalaxyFitsAlloc();
    260     }
    261 
    262     float fRmajorBest = NAN;
    263     float fRminorBest = NAN;
    264     float chisqBest = NAN;
    265     for (float fRmajor = opt->fRmajorMin; fRmajor < opt->fRmajorMax + 0.5*opt->fRmajorDel; fRmajor += opt->fRmajorDel) {
    266         for (float fRminor = opt->fRminorMin; fRminor < opt->fRminorMax + 0.5*opt->fRminorDel; fRminor += opt->fRminorDel) {
    267  
    268             psEllipseAxes testAxes = guessAxes;
    269             testAxes.major = guessAxes.major * fRmajor;
    270             testAxes.minor = guessAxes.minor * fRminor;
    271            
    272             pmPSF_AxesToModel (PAR, testAxes, modelType);
    273            
    274             psphotGalaxyShapeSource (pcm, source, maskVal, psfSize, true);
    275 
    276             int i = source->galaxyFits->chisq->n - 1;
    277             float flux = source->galaxyFits->Flux->data.F32[i];
    278             if (isfinite(flux)) {
    279                 float thisChisq = source->galaxyFits->chisq->data.F32[i];
    280                 if (isfinite(thisChisq) && isfinite(flux) && (!isfinite(chisqBest) || thisChisq < chisqBest)) {
    281                     chisqBest = thisChisq;
    282                     fRmajorBest = fRmajor;
    283                     fRminorBest = fRminor;
     253
     254    for (int iModel = 0 ; iModel < source->modelFits->n; iModel++) {
     255        pmModel *model = source->modelFits->data[iModel];
     256        if (!model) return false;
     257
     258        pmModelType modelType = model->type;
     259        model->flags = PM_MODEL_STATUS_NONE;
     260
     261        // we are using fitOptions->mode : be sure this makes sense
     262        pmPCMdata *pcm = pmPCMinit (source, fitOptions, model, maskVal, psfSize);
     263        if (!pcm) return false;
     264
     265        // we are fitting only PM_PAR_I0; the shape elements are generated from a grid
     266        psF32 *PAR = pcm->modelConv->params->data.F32;
     267
     268        pmSourceGalaxyFits *galaxyFits = pmSourceGalaxyFitsAlloc();
     269
     270        // set the options for this source
     271        if (!psphotGalaxyShapeOptionsSet(source, galaxyFits, opt)) {
     272            // this source won't work
     273            psFree(pcm);
     274            psFree(galaxyFits);
     275            continue;
     276        }
     277
     278        if (!source->galaxyFits) {
     279            source->galaxyFits = psArrayAllocEmpty(1);
     280        }
     281        psArrayAdd(source->galaxyFits, 1, galaxyFits);
     282        psFree(galaxyFits);
     283
     284        // I have some source guess (e0, e1, e2)
     285        psEllipseAxes guessAxes = pmPSF_ModelToAxes (PAR, modelType);
     286
     287        float fRmajorBest = NAN;
     288        float fRminorBest = NAN;
     289        float chisqBest = NAN;
     290        for (float fRmajor = galaxyFits->fRmajorMin; fRmajor < galaxyFits->fRmajorMax + 0.5*galaxyFits->fRmajorDel; fRmajor += galaxyFits->fRmajorDel) {
     291            for (float fRminor = galaxyFits->fRminorMin; fRminor < galaxyFits->fRminorMax + 0.5*galaxyFits->fRminorDel; fRminor += galaxyFits->fRminorDel) {
     292     
     293                psEllipseAxes testAxes = guessAxes;
     294                testAxes.major = guessAxes.major * fRmajor;
     295                testAxes.minor = guessAxes.minor * fRminor;
     296               
     297                pmPSF_AxesToModel (PAR, testAxes, modelType);
     298               
     299                psphotGalaxyShapeSource (pcm, source, galaxyFits, maskVal, psfSize, true);
     300
     301                int i = galaxyFits->chisq->n - 1;
     302                float flux = galaxyFits->Flux->data.F32[i];
     303                if (isfinite(flux)) {
     304                    float thisChisq = galaxyFits->chisq->data.F32[i];
     305                    if (isfinite(thisChisq) && isfinite(flux) && (!isfinite(chisqBest) || thisChisq < chisqBest)) {
     306                        chisqBest = thisChisq;
     307                        fRmajorBest = fRmajor;
     308                        fRminorBest = fRminor;
     309                    }
    284310                }
     311                // reset I0 to avoid potential problems on the next iteration
     312                PAR[PM_PAR_I0] = 1.0;
    285313            }
    286             // reset I0 to avoid potential problems on the next iteration
    287             PAR[PM_PAR_I0] = 1.0;
    288         }
    289     }
    290 
    291 #define SAVE_BEST_MODEL
    292 #ifdef SAVE_BEST_MODEL
    293     // Save model with smallest chisq
    294     if (isfinite(chisqBest)) {
    295 #else
    296     // Save model with nominal parameters
    297     {
    298         fRmajorBest = 1;
    299         fRminorBest = 1;
     314        }
     315
     316        if (isfinite(chisqBest)) {
     317            // now save the best fitting model as the source's extended model ...
     318            psEllipseAxes testAxes = guessAxes;
     319
     320            // ... unless this macro is defined
     321#ifndef SAVE_NOMINAL_MODEL
     322            testAxes.major = guessAxes.major * fRmajorBest;
     323            testAxes.minor = guessAxes.minor * fRminorBest;
    300324#endif
    301         // now save the best fitting model as the source's extended model
    302         psEllipseAxes testAxes = guessAxes;
    303         testAxes.major = guessAxes.major * fRmajorBest;
    304         testAxes.minor = guessAxes.minor * fRminorBest;
    305        
    306         pmPSF_AxesToModel (PAR, testAxes, modelType);
    307        
    308         psphotGalaxyShapeSource (pcm, source, maskVal, psfSize, false);
    309 
    310         // Replace modelEXT with this model, if the model is good
    311         if (isfinite(PAR[PM_PAR_I0])) {
    312             psFree (source->modelEXT);
    313 
    314             source->modelEXT = psMemIncrRefCounter (pcm->modelConv);
    315             source->type = PM_SOURCE_TYPE_EXTENDED;
    316             source->mode |= PM_SOURCE_MODE_EXTMODEL;
    317             source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
    318 
    319             // cache the model flux
    320             pmPCMCacheModel (source, maskVal, psfSize, fitOptions->nsigma);
    321         }
    322     }
    323 
    324     psFree (pcm);
     325           
     326            pmPSF_AxesToModel (PAR, testAxes, modelType);
     327               
     328            psphotGalaxyShapeSource (pcm, source, galaxyFits, maskVal, psfSize, false);
     329
     330            // Replace modelEXT with the best model from the first of the model fits if one of them is good
     331            if (isfinite(PAR[PM_PAR_I0]) && modelType == opt->extModelType) {
     332                psFree (source->modelEXT);
     333
     334                source->modelEXT = psMemIncrRefCounter (pcm->modelConv);
     335                source->type = PM_SOURCE_TYPE_EXTENDED;
     336                source->mode |= PM_SOURCE_MODE_EXTMODEL;
     337                source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
     338
     339                // cache the model flux
     340                pmPCMCacheModel (source, maskVal, psfSize, fitOptions->nsigma);
     341            }
     342        }
     343
     344        psFree (pcm);
     345    }
    325346    return true;
    326347}
     
    328349// fit the given model to the source and find chisq & normalization
    329350// XXX is this a single-component model? sersic with a supplied index, Reff, axis ratio, and theta?
    330 bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, int psfSize, bool saveResults) {
     351bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, pmSourceGalaxyFits *galaxyFits, psImageMaskType maskVal, int psfSize, bool saveResults) {
    331352
    332353    PS_ASSERT_PTR_NON_NULL(source, false);
     
    384405
    385406    if (saveResults) {
    386         psVectorAppend (source->galaxyFits->Flux, flux);
    387         psVectorAppend (source->galaxyFits->dFlux, dflux);
    388         psVectorAppend (source->galaxyFits->chisq, Chisq);
    389         source->galaxyFits->nPix = nPix;
     407        psVectorAppend (galaxyFits->Flux, flux);
     408        psVectorAppend (galaxyFits->dFlux, dflux);
     409        psVectorAppend (galaxyFits->chisq, Chisq);
     410        galaxyFits->nPix = nPix;
     411        galaxyFits->modelType = pcm->modelConv->type;
    390412    }
    391413
     
    404426    psMemSetDeallocator(opt, (psFreeFunc) psphotGalaxyShapeOptionsFree);
    405427   
    406     opt->fRmajorMin = 0.5;
    407     opt->fRmajorMax = 2.0;
    408     opt->fRmajorDel = 0.1;
    409     opt->fRminorMin = 0.5;
    410     opt->fRminorMax = 2.0;
    411     opt->fRminorDel = 0.1;
    412 
    413428    return opt;
    414429}
    415430
     431bool psphotGalaxyShapeOptionsSet(pmSource *source, pmSourceGalaxyFits *galaxyFits, psphotGalaxyShapeOptions *options)
     432{
     433    // XXX: put these in recipe
     434    // doesn't make sense to use too small of a spacing
     435    float clampedSN = source->extSN < options->clampSN ? source->extSN : options->clampSN;
     436
     437    float f_del = options->Q / clampedSN;
     438    float f_min = 1 - options->NSigma * f_del;
     439    float f_max = 1 + options->NSigma * f_del;
     440
     441    // if f_min goes negative skip this object
     442    if (f_min < 0) return false;
     443
     444    galaxyFits->fRmajorMin = f_min;
     445    galaxyFits->fRmajorMax = f_max;
     446    galaxyFits->fRmajorDel = f_del;
     447    galaxyFits->fRminorMin = f_min;
     448    galaxyFits->fRminorMax = f_max;
     449    galaxyFits->fRminorDel = f_del;
     450
     451    return true;
     452}
     453
  • branches/eam_branches/ipp-20140423/psphot/src/psphotKronIterate.c

    r36375 r36828  
    532532            source->moments->KronFlux  = NAN;
    533533            source->moments->KronFluxErr  = NAN;
     534            source->moments->KronFinner = NAN;
     535            source->moments->KronFouter = NAN;
    534536            return false;
    535537        }
  • branches/eam_branches/ipp-20140423/psphot/src/psphotStackImageLoop.c

    • Property svn:mergeinfo changed (with no actual effect on merging)
Note: See TracChangeset for help on using the changeset viewer.