IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/psphot

  • branches/simtest_nebulous_branches/psphot/src

    • Property svn:ignore
      •  

        old new  
        1818psphotVersionDefinitions.h
        1919psphotMomentsStudy
         20psphotPetrosianStudy
         21psphotForced
         22psphotMakePSF
         23psphotStack
  • branches/simtest_nebulous_branches/psphot/src/psphotFitSourcesLinearStack.c

    r24584 r27840  
    11# include "psphotInternal.h"
     2// XXX need array of covar factors for each image
     3// XXX define the 'good' / 'bad' flags?
    24
    3 // fit flux (and optionally sky model) to all reasonable sources
    4 // with the linear fitting process.  sources must have an associated
    5 // model with selected pixels, and the fit radius must be defined
     5# define COVAR_FACTOR 1.0
    66
    7 // given the set of sources, each of which points to the pixels in the
    8 // science image, we construct a set of simulated sources with their own pixels.
    9 // these are used to determine the simultaneous linear fit of fluxes.
    10 // the analysis is performed wrt the simulated pixel values
    11 
    12 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal);
    13 
    14 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) {
     7bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final) {
    158
    169    bool status;
    17     float x;
    18     float y;
    1910    float f;
    20     // float r;
     11
     12    // select the appropriate recipe information
     13    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     14    assert (recipe);
    2115
    2216    psTimerStart ("psphot.linear");
     
    3327    maskVal |= markVal;
    3428
    35     // source analysis is done in spatial order
    36     sources = psArraySort (sources, pmSourceSortByY);
     29    // analysis is done in spatial order (to speed up overlap search)
     30    // sort by first element in each source list
     31    objects = psArraySort (objects, pmPhotObjSortByX);
    3732
    3833    // storage array for fitSources
    39     psArray *fitSources = psArrayAllocEmpty (sources->n);
     34    psArray *fitSources = psArrayAllocEmpty (objects->n);
    4035
    41     bool CONSTANT_PHOTOMETRIC_WEIGHTS =
    42         psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
    43     if (!status) {
    44         psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
    45     }
     36    bool CONSTANT_PHOTOMETRIC_WEIGHTS = psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
     37    psAssert (status, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
     38
     39    // XXX store a local static array of covar factors for each of the images (by image ID)
     40    // float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     41    // psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor);
    4642
    4743    // select the sources which will be used for the fitting analysis
    48     for (int i = 0; i < sources->n; i++) {
    49         pmSource *source = sources->data[i];
     44    for (int i = 0; i < objects->n; i++) {
     45        pmPhotObj *object = objects->data[i];
     46        if (!object) continue;
     47        if (!object->sources) continue;
    5048
    51         // turn this bit off and turn it on again if we pass this test
    52         source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
     49        // XXX check an element of the group to see if we should use it
     50        // if (!object->flags & PM_PHOT_OBJ_BAD) continue;
    5351
    54         // skip non-astronomical objects (very likely defects)
    55         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    56         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
     52        for (int j = 0; j < object->sources->n; j++) {
     53          pmSource *source = object->sources->data[j];
     54          if (!source) continue;
    5755
    58         // do not include CRs in the full ensemble fit
    59         if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
     56          // turn this bit off and turn it on again if we keep this source
     57          source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
    6058
    61         if (final) {
    62             if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
    63         } else {
    64             if (source->mode & PM_SOURCE_MODE_BLEND) continue;
    65         }
     59          // generate model for sources without, or skip if we can't
     60          if (!source->modelFlux) {
     61            if (!pmSourceCacheModel (source, maskVal)) continue;
     62          }
    6663
    67         // generate model for sources without, or skip if we can't
    68         if (!source->modelFlux) {
    69             if (!pmSourceCacheModel (source, maskVal)) continue;
    70         }
    71 
    72         source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
    73         psArrayAdd (fitSources, 100, source);
     64          source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
     65          psArrayAdd (fitSources, 100, source);
     66        }
    7467    }
    75     psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);
     68    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), objects->n);
    7669
    7770    if (fitSources->n == 0) {
     
    8376    psVector *errors = psVectorAlloc (fitSources->n, PS_TYPE_F32);
    8477
    85     // create the border matrix (includes the sparse matrix)
    86     // for just sky: 1 row; for x,y terms: 3 rows
     78    // create the sparse matrix
    8779    psSparse *sparse = psSparseAlloc (fitSources->n, 100);
    88     psSparseBorder *border = psSparseBorderAlloc (sparse, 1);
    8980
    9081    // fill out the sparse matrix elements and border elements (B)
     
    9586
    9687        // diagonal elements of the sparse matrix (auto-cross-product)
    97         f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     88        f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    9889        psSparseMatrixElement (sparse, i, i, f);
    9990
    10091        // the formal error depends on the weighting scheme
    10192        if (CONSTANT_PHOTOMETRIC_WEIGHTS) {
    102             float var = pmSourceModelDotModel (SRCi, SRCi, false);
     93            float var = pmSourceModelDotModel (SRCi, SRCi, false, COVAR_FACTOR);
    10394            errors->data.F32[i] = 1.0 / sqrt(var);
    10495        } else {
     
    10697        }
    10798
    108 
    10999        // find the image x model value
    110         f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     100        f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    111101        psSparseVectorElement (sparse, i, f);
    112 
    113         f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS);
    114         psSparseBorderElementB (border, i, 0, f);
    115102
    116103        // loop over all other stars following this one
     
    118105            pmSource *SRCj = fitSources->data[j];
    119106
     107            // we only need to generate dot terms for source on the same image
     108            if (SRCj->imageID != SRCi->imageID) { continue; }
     109
    120110            // skip over disjoint source images, break after last possible overlap
    121             if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) break;
    122             if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;
    123             if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) continue;
    124             if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;
     111            if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;  // source(i) is above source(j)
     112            if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) continue;  // source(i) is below source(j)
     113            if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;  // source(i) is right of source(j)
     114            if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) break;     // source(i) is left of source(j) [no other source(j) can overlap source(i)]
    125115
    126116            // got an overlap; calculate cross-product and add to output array
    127             f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS);
     117            f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    128118            psSparseMatrixElement (sparse, j, i, f);
    129119        }
     
    133123    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    134124
    135     // set the sky, sky_x, sky_y components of border matrix
    136     SetBorderMatrixElements (border, readout, fitSources, CONSTANT_PHOTOMETRIC_WEIGHTS, SKY_FIT_ORDER, markVal);
    137 
    138125    psSparseConstraint constraint;
    139126    constraint.paramMin   = 0.0;
     
    142129
    143130    // solve for normalization terms (need include local sky?)
    144     psVector *norm = psSparseSolve (NULL, constraint, sparse, 5);
    145 
     131    psVector *norm = NULL;
     132    norm = psSparseSolve (NULL, constraint, sparse, 5);
    146133    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    147 
    148     // XXXX **** philosophical question:
    149     // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:
    150     // should retain the chisq and errors from the intermediate non-linear fit?
    151     // the non-linear fit provides better values for the position errors, and for
    152     // extended sources, the shape errors
    153134
    154135    // adjust I0 for fitSources and subtract
     
    164145        model->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
    165146        model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
    166         // XXX is the value of 'errors' modified by the sky fit?
    167147
    168148        // subtract object
    169149        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    170         source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
    171150    }
    172151    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "sub models: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    173152
    174153    // measure chisq for each source
    175     for (int i = 0; final && (i < fitSources->n); i++) {
     154    // for (int i = 0; final && (i < fitSources->n); i++) {
     155    for (int i = 0; i < fitSources->n; i++) {
    176156        pmSource *source = fitSources->data[i];
    177157        if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue;
    178158        pmModel *model = pmSourceGetModel (NULL, source);
    179         pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal);
     159        pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, COVAR_FACTOR);
    180160    }
    181161    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
     
    186166    psFree (norm);
    187167    psFree (errors);
    188     psFree (border);
    189168
    190169    psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
    191 
    192     psphotVisualShowResidualImage (readout);
    193     psphotVisualShowFlags (sources);
    194170
    195171    return true;
    196172}
    197173
    198 // Calculate the weight terms for the sky fit component of the matrix.  This function operates
    199 // on the pixels which correspond to all of the sources of interest.  These elements fill in
    200 // the border matrix components in the sparse matrix equation.
    201 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal) {
     174// sort by X (ascending)
     175int pmPhotObjSortByX (const void **a, const void **b)
     176{
     177    pmPhotObj *objA = *(pmPhotObj **)a;
     178    pmPhotObj *objB = *(pmPhotObj **)b;
    202179
    203     // generate the image-wide weight terms
    204     // turn on MARK for all image pixels
    205     psRegion fullArray = psRegionSet (0, 0, 0, 0);
    206     fullArray = psRegionForImage (readout->mask, fullArray);
    207     psImageMaskRegion (readout->mask, fullArray, "OR", markVal);
     180    psF32 fA = objA->x;
     181    psF32 fB = objB->x;
    208182
    209     // turn off MARK for all object pixels
    210     for (int i = 0; i < sources->n; i++) {
    211         pmSource *source = sources->data[i];
    212         pmModel *model = pmSourceGetModel (NULL, source);
    213         if (model == NULL) continue;
    214         float x = model->params->data.F32[PM_PAR_XPOS];
    215         float y = model->params->data.F32[PM_PAR_YPOS];
    216         psImageMaskCircle (source->maskView, x, y, model->radiusFit, "AND", PS_NOT_IMAGE_MASK(markVal));
    217     }
    218 
    219     // accumulate the image statistics from the masked regions
    220     psF32 **image  = readout->image->data.F32;
    221     psF32 **variance = readout->variance->data.F32;
    222     psImageMaskType  **mask   = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA;
    223 
    224     double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy;
    225     w = x = y = x2 = xy = y2 = fo = fx = fy = 0;
    226 
    227     int col0 = readout->image->col0;
    228     int row0 = readout->image->row0;
    229 
    230     for (int j = 0; j < readout->image->numRows; j++) {
    231         for (int i = 0; i < readout->image->numCols; i++) {
    232             if (mask[j][i]) continue;
    233             if (constant_weights) {
    234                 wt = 1.0;
    235             } else {
    236                 wt = variance[j][i];
    237             }
    238             f = image[j][i];
    239             w   += 1/wt;
    240             fo  += f/wt;
    241         }
    242     }
    243 
    244     // turn off MARK for all image pixels
    245     psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal));
    246 
    247     // set the Border T elements
    248     psSparseBorderElementG (border, 0, fo);
    249     psSparseBorderElementT (border, 0, 0, w);
    250 
    251     return true;
     183    psF32 diff = fA - fB;
     184    if (diff > FLT_EPSILON) return (+1);
     185    if (diff < FLT_EPSILON) return (-1);
     186    return (0);
    252187}
Note: See TracChangeset for help on using the changeset viewer.