IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 31, 2010, 7:02:48 PM (16 years ago)
Author:
eugene
Message:

minor work on psphotStack

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/psphotFitSourcesLinearStack.c

    r27532 r27547  
    11# include "psphotInternal.h"
    22
    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
    6 
    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 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) {
     3// for now, let's store the detections on the readout->analysis for each readout
     4bool psphotFitSourcesLinearStack (pmConfig *config, const pmFPAview *view, bool final)
     5{
     6    bool status = true;
     7
     8    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     9    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     10
     11    // loop over the available readouts
     12    for (int i = 0; i < num; i++) {
     13        if (!psphotFitSourcesLinearReadoutStack (config, view, "PSPHOT.INPUT", i, final)) {
     14            psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (linear) for PSPHOT.INPUT entry %d", i);
     15            return false;
     16        }
     17    }
     18    return true;
     19}
     20
     21bool psphotFitSourcesLinearReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, bool final) {
    1322
    1423    bool status;
     
    1827    // float r;
    1928
     29    // select the appropriate recipe information
     30    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     31    assert (recipe);
     32
     33    // find the currently selected readout
     34    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
     35    psAssert (file, "missing file?");
     36
     37    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     38    psAssert (readout, "missing readout?");
     39
     40    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     41    psAssert (detections, "missing detections?");
     42
     43    psArray *sources = detections->allSources;
     44    psAssert (sources, "missing sources?");
     45
     46    if (!sources->n) {
     47        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping linear fit");
     48        return true;
     49    }
     50
     51    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
     52    psAssert (sources, "missing psf?");
     53
    2054    psTimerStart ("psphot.linear");
    2155
     
    3670    // storage array for fitSources
    3771    psArray *fitSources = psArrayAllocEmpty (sources->n);
     72
     73    // option to limit analysis to a specific region
     74    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
     75    psRegion AnalysisRegion = psRegionFromString (region);
     76    AnalysisRegion = psRegionForImage (readout->image, AnalysisRegion);
     77    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
    3878
    3979    bool CONSTANT_PHOTOMETRIC_WEIGHTS =
     
    4282        psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
    4383    }
     84    int SKY_FIT_ORDER = psMetadataLookupS32(&status, recipe, "SKY_FIT_ORDER");
     85    if (!status) {
     86        SKY_FIT_ORDER = 0;
     87    }
     88    bool SKY_FIT_LINEAR = psMetadataLookupBool(&status, recipe, "SKY_FIT_LINEAR");
     89    if (!status) {
     90        SKY_FIT_LINEAR = false;
     91    }
     92
     93    // XXX test: choose a larger-than expected radius:
     94    float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     95    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor);
     96
     97    // XXX do not apply covarFactor for the moment...
     98    // covarFactor = 1.0;
    4499
    45100    // select the sources which will be used for the fitting analysis
    46     for (int i = 0; i < sources->n; i++) {
    47         pmSource *source = sources->data[i];
    48 
    49         // turn this bit off and turn it on again if we pass this test
    50         source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
    51 
    52         // skip non-astronomical objects (very likely defects)
    53         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    54         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    55 
    56         // do not include CRs in the full ensemble fit
    57         if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
    58 
    59         if (final) {
    60             if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
    61         } else {
    62             if (source->mode & PM_SOURCE_MODE_BLEND) continue;
    63         }
    64 
    65         // generate model for sources without, or skip if we can't
    66         if (!source->modelFlux) {
     101    for (int i = 0; i < objects->n; i++) {
     102        pmPhotObj *object = objects->data[i];
     103        if (!object) continue;
     104        if (!object->sources) continue;
     105
     106        // check an element of the group to see if we should use it
     107        if (!object->flags & PM_PHOT_OBJ_BAD) continue;
     108
     109        for (int j = 0; j < object->sources->n; j++) {
     110          pmSource *source = object->sources->data[j];
     111          if (!source) continue;
     112
     113          // turn this bit off and turn it on again if we keep this source
     114          source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
     115
     116          // generate model for sources without, or skip if we can't
     117          if (!source->modelFlux) {
    67118            if (!pmSourceCacheModel (source, maskVal)) continue;
    68         }
    69 
    70         source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
    71         psArrayAdd (fitSources, 100, source);
     119          }
     120
     121          source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
     122          psArrayAdd (fitSources, 100, source);
     123        }
    72124    }
    73125    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);
     
    81133    psVector *errors = psVectorAlloc (fitSources->n, PS_TYPE_F32);
    82134
    83     // create the border matrix (includes the sparse matrix)
    84     // for just sky: 1 row; for x,y terms: 3 rows
     135    // create the sparse matrix
    85136    psSparse *sparse = psSparseAlloc (fitSources->n, 100);
    86     psSparseBorder *border = psSparseBorderAlloc (sparse, 1);
    87137
    88138    // fill out the sparse matrix elements and border elements (B)
     
    93143
    94144        // diagonal elements of the sparse matrix (auto-cross-product)
    95         f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     145        f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
    96146        psSparseMatrixElement (sparse, i, i, f);
    97147
    98148        // the formal error depends on the weighting scheme
    99149        if (CONSTANT_PHOTOMETRIC_WEIGHTS) {
    100             float var = pmSourceModelDotModel (SRCi, SRCi, false);
     150            float var = pmSourceModelDotModel (SRCi, SRCi, false, covarFactor);
    101151            errors->data.F32[i] = 1.0 / sqrt(var);
    102152        } else {
     
    104154        }
    105155
    106 
    107156        // find the image x model value
    108         f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     157        f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
    109158        psSparseVectorElement (sparse, i, f);
    110 
    111         f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS);
    112         psSparseBorderElementB (border, i, 0, f);
    113159
    114160        // loop over all other stars following this one
    115161        for (int j = i + 1; j < fitSources->n; j++) {
    116162            pmSource *SRCj = fitSources->data[j];
     163
     164            // XXX I need to know if this source is on the same image as SRCi --
     165            if (!sameImge) { continue; }
    117166
    118167            // skip over disjoint source images, break after last possible overlap
     
    123172
    124173            // got an overlap; calculate cross-product and add to output array
    125             f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS);
     174            f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
    126175            psSparseMatrixElement (sparse, j, i, f);
    127176        }
     
    130179    psSparseResort (sparse);
    131180    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    132 
    133     // set the sky, sky_x, sky_y components of border matrix
    134     SetBorderMatrixElements (border, readout, fitSources, CONSTANT_PHOTOMETRIC_WEIGHTS, SKY_FIT_ORDER, markVal);
    135181
    136182    psSparseConstraint constraint;
     
    140186
    141187    // solve for normalization terms (need include local sky?)
    142     psVector *norm = psSparseSolve (NULL, constraint, sparse, 5);
    143 
     188    psVector *norm = NULL;
     189    norm = psSparseSolve (NULL, constraint, sparse, 5);
    144190    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    145191
     
    170216
    171217    // measure chisq for each source
    172     for (int i = 0; final && (i < fitSources->n); i++) {
     218    // for (int i = 0; final && (i < fitSources->n); i++) {
     219    for (int i = 0; i < fitSources->n; i++) {
    173220        pmSource *source = fitSources->data[i];
    174221        if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue;
    175222        pmModel *model = pmSourceGetModel (NULL, source);
    176         pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal);
     223        pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, covarFactor);
    177224    }
    178225    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
     
    182229    psFree (fitSources);
    183230    psFree (norm);
     231    psFree (skyfit);
    184232    psFree (errors);
    185233    psFree (border);
     
    188236
    189237    psphotVisualShowResidualImage (readout);
    190     psphotVisualShowFlags (sources);
     238    psphotVisualPlotChisq (sources);
     239    // psphotVisualShowFlags (sources);
     240
     241    // We have to place this visualization here because the models are not realized until
     242    // psphotGuessModels or fitted until psphotFitSourcesLinear.
     243    psphotVisualShowPSFStars (recipe, psf, sources);
    191244
    192245    return true;
    193246}
     247
     248// XXX do we need this?
     249// XXX disallow the simultaneous sky fit and remove this code...
     250
     251// Calculate the weight terms for the sky fit component of the matrix.  This function operates
     252// on the pixels which correspond to all of the sources of interest.  These elements fill in
     253// the border matrix components in the sparse matrix equation.
     254static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, int SKY_FIT_ORDER, psImageMaskType markVal) {
     255
     256    // generate the image-wide weight terms
     257    // turn on MARK for all image pixels
     258    psRegion fullArray = psRegionSet (0, 0, 0, 0);
     259    fullArray = psRegionForImage (readout->mask, fullArray);
     260    psImageMaskRegion (readout->mask, fullArray, "OR", markVal);
     261
     262    // turn off MARK for all object pixels
     263    for (int i = 0; i < sources->n; i++) {
     264        pmSource *source = sources->data[i];
     265        pmModel *model = pmSourceGetModel (NULL, source);
     266        if (model == NULL) continue;
     267        float x = model->params->data.F32[PM_PAR_XPOS];
     268        float y = model->params->data.F32[PM_PAR_YPOS];
     269        psImageMaskCircle (source->maskView, x, y, model->fitRadius, "AND", PS_NOT_IMAGE_MASK(markVal));
     270    }
     271
     272    // accumulate the image statistics from the masked regions
     273    psF32 **image  = readout->image->data.F32;
     274    psF32 **variance = readout->variance->data.F32;
     275    psImageMaskType  **mask   = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA;
     276
     277    double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy;
     278    w = x = y = x2 = xy = y2 = fo = fx = fy = 0;
     279
     280    int col0 = readout->image->col0;
     281    int row0 = readout->image->row0;
     282
     283    for (int j = 0; j < readout->image->numRows; j++) {
     284        for (int i = 0; i < readout->image->numCols; i++) {
     285            if (mask[j][i]) continue;
     286            if (constant_weights) {
     287                wt = 1.0;
     288            } else {
     289                wt = variance[j][i];
     290            }
     291            f = image[j][i];
     292            w   += 1/wt;
     293            fo  += f/wt;
     294            if (SKY_FIT_ORDER == 0) continue;
     295
     296            xc  = i + col0;
     297            yc  = j + row0;
     298            x  +=    xc/wt;
     299            y  +=    yc/wt;
     300            x2 += xc*xc/wt;
     301            xy += xc*yc/wt;
     302            y2 += yc*yc/wt;
     303            fx +=  f*xc/wt;
     304            fy +=  f*yc/wt;
     305        }
     306    }
     307
     308    // turn off MARK for all image pixels
     309    psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal));
     310
     311    // set the Border T elements
     312    psSparseBorderElementG (border, 0, fo);
     313    psSparseBorderElementT (border, 0, 0, w);
     314    if (SKY_FIT_ORDER > 0) {
     315        psSparseBorderElementG (border, 0, fx);
     316        psSparseBorderElementG (border, 0, fy);
     317        psSparseBorderElementT (border, 1, 0, x);
     318        psSparseBorderElementT (border, 2, 0, y);
     319        psSparseBorderElementT (border, 0, 1, x);
     320        psSparseBorderElementT (border, 1, 1, x2);
     321        psSparseBorderElementT (border, 2, 1, xy);
     322        psSparseBorderElementT (border, 0, 2, y);
     323        psSparseBorderElementT (border, 1, 2, xy);
     324        psSparseBorderElementT (border, 2, 2, y2);
     325    }
     326
     327    return true;
     328}
Note: See TracChangeset for help on using the changeset viewer.