IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 16, 2006, 4:24:03 PM (20 years ago)
Author:
Paul Price
Message:

NOT_U8 and NOT_U16 macros were moved into psLib (and renamed with PS_ prefix). Updating files that use these macros so that they compile.

File:
1 edited

Legend:

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

    r9576 r9595  
    44// 2006.02.07 : no leaks!
    55// fit all reasonable sources with the linear PSF model
    6 bool psphotEnsemblePSF (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) { 
     6bool psphotEnsemblePSF (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) {
    77
    88    bool  status;
     
    3939
    4040    const bool CONSTANT_PHOTOMETRIC_WEIGHTS =
    41         psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
     41        psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
    4242    if (!status) {
    43         psAbort(PS_FILE_LINE, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
     43        psAbort(PS_FILE_LINE, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
    4444    }
    4545
    4646    for (int i = 0; i < sources->n; i++) {
    47         pmSource *inSource = sources->data[i];
    48 
    49         // skip non-astronomical objects (very likely defects)
    50         // XXX EAM : should we try these anyway?
    51         if (inSource->type == PM_SOURCE_TYPE_DEFECT) continue;
    52         if (inSource->type == PM_SOURCE_TYPE_SATURATED) continue;
    53         if (final) {
    54             if (inSource->mode &  PM_SOURCE_MODE_SUBTRACTED) continue;
    55         } else {
    56             if (inSource->mode &  PM_SOURCE_MODE_BLEND) continue;
    57         }
    58 
    59         if (inSource->moments->x < AnalysisRegion.x0) continue;
    60         if (inSource->moments->y < AnalysisRegion.y0) continue;
    61         if (inSource->moments->x > AnalysisRegion.x1) continue;
    62         if (inSource->moments->y > AnalysisRegion.y1) continue;
    63 
    64         pmSource *otSource = pmSourceAlloc ();
    65 
    66         // really saturated stars should be re-measured for a better centroid
    67         // XXX EAM : move this to a 'clear satstar function'
    68         if (inSource->mode &  PM_SOURCE_MODE_SATSTAR) {
    69             status = pmSourceMoments (inSource, INNER_RADIUS);
    70         }
    71 
    72         // XXX EAM : add option to use EXT or PSF form
    73         // use the source moments, etc to guess basic model parameters
    74         pmModel *modelEXT = pmSourceModelGuess (inSource, psf->type);
    75         if (inSource->mode &  PM_SOURCE_MODE_SATSTAR) {
    76             modelEXT->params->data.F32[PM_PAR_XPOS] = inSource->moments->x;
    77             modelEXT->params->data.F32[PM_PAR_YPOS] = inSource->moments->y;
    78         } else {
    79             // peak-up on peak (for non-sat objects)
    80 
    81             // ix,iy must land on inSource->pixels
    82             int ix = PS_MAX (inSource->pixels->col0 + 1, PS_MIN (inSource->pixels->col0 + inSource->pixels->numCols - 2, inSource->peak->x));
    83             int iy = PS_MAX (inSource->pixels->row0 + 1, PS_MIN (inSource->pixels->row0 + inSource->pixels->numRows - 2, inSource->peak->y));
    84 
    85             psPolynomial2D *bicube = psImageBicubeFit (inSource->pixels, ix, iy);
    86             psPlane min = psImageBicubeMin (bicube);
    87 
    88             psTrace ("psphot", 5, "peak coord: %f %f -> %f %f\n",
    89                      modelEXT->params->data.F32[PM_PAR_XPOS], modelEXT->params->data.F32[PM_PAR_YPOS], min.x + ix, min.y + iy);
    90            
    91             // if min point is too deviant, keep the old value
    92             if ((fabs(min.x) < 1.5) && (fabs(min.y) < 1.5)) {
    93                 modelEXT->params->data.F32[PM_PAR_XPOS] = min.x + ix;
    94                 modelEXT->params->data.F32[PM_PAR_YPOS] = min.y + iy;
    95             }
    96             psFree (bicube);
    97         }
    98 
    99         // set PSF parameters for this model
    100         pmModel *model = pmModelFromPSF (modelEXT, psf);
    101         psFree (modelEXT);
    102 
    103         // save the original coords
    104         x = model->params->data.F32[PM_PAR_XPOS];
    105         y = model->params->data.F32[PM_PAR_YPOS];
    106 
    107         // set the fit radius based on the object flux limit and the model
    108         psphotCheckRadiusPSF (readout, inSource, model);
    109 
    110         // make temporary copies of the image pixels and mask
    111         otSource->mask   = psImageCopy (NULL, inSource->mask,   PS_TYPE_U8);
    112         otSource->pixels = psImageCopy (NULL, inSource->pixels, PS_TYPE_F32);
    113         otSource->weight = psImageCopy (NULL, inSource->weight, PS_TYPE_F32);
    114 
    115         // build the model image
    116         psImage *flux = otSource->pixels;
    117         psImage *mask = otSource->mask;
    118 
    119         // set model to unit peak, zero sky (we assume sky is subtracted)
    120         model->params->data.F32[PM_PAR_SKY] = 0.0;
    121         model->params->data.F32[PM_PAR_I0] = 1.0;
    122 
    123         // fill in the model pixel values
    124         psImageInit (flux, 0.0);
    125         psImageKeepCircle (mask, x, y, model->radiusTMP, "OR", PM_MASK_MARK);
    126         pmModelAdd (flux, mask, model, false, false);
    127 
    128         // calculate nDOF (nPix - 1)
    129         // int Nmaskpix = psImageCountPixelMask (mask, allArray, PM_MASK_SAT);
    130         // model->nDOF  = mask->numCols*mask->numRows - Nmaskpix - 1;
    131 
    132         // save source in list
    133         otSource->modelPSF = model;
    134         index->data.U32[models->n] = i;
    135         psArrayAdd (models, 100, otSource);
    136         psFree (otSource);
     47        pmSource *inSource = sources->data[i];
     48
     49        // skip non-astronomical objects (very likely defects)
     50        // XXX EAM : should we try these anyway?
     51        if (inSource->type == PM_SOURCE_TYPE_DEFECT) continue;
     52        if (inSource->type == PM_SOURCE_TYPE_SATURATED) continue;
     53        if (final) {
     54            if (inSource->mode &  PM_SOURCE_MODE_SUBTRACTED) continue;
     55        } else {
     56            if (inSource->mode &  PM_SOURCE_MODE_BLEND) continue;
     57        }
     58
     59        if (inSource->moments->x < AnalysisRegion.x0) continue;
     60        if (inSource->moments->y < AnalysisRegion.y0) continue;
     61        if (inSource->moments->x > AnalysisRegion.x1) continue;
     62        if (inSource->moments->y > AnalysisRegion.y1) continue;
     63
     64        pmSource *otSource = pmSourceAlloc ();
     65
     66        // really saturated stars should be re-measured for a better centroid
     67        // XXX EAM : move this to a 'clear satstar function'
     68        if (inSource->mode &  PM_SOURCE_MODE_SATSTAR) {
     69            status = pmSourceMoments (inSource, INNER_RADIUS);
     70        }
     71
     72        // XXX EAM : add option to use EXT or PSF form
     73        // use the source moments, etc to guess basic model parameters
     74        pmModel *modelEXT = pmSourceModelGuess (inSource, psf->type);
     75        if (inSource->mode &  PM_SOURCE_MODE_SATSTAR) {
     76            modelEXT->params->data.F32[PM_PAR_XPOS] = inSource->moments->x;
     77            modelEXT->params->data.F32[PM_PAR_YPOS] = inSource->moments->y;
     78        } else {
     79            // peak-up on peak (for non-sat objects)
     80
     81            // ix,iy must land on inSource->pixels
     82            int ix = PS_MAX (inSource->pixels->col0 + 1, PS_MIN (inSource->pixels->col0 + inSource->pixels->numCols - 2, inSource->peak->x));
     83            int iy = PS_MAX (inSource->pixels->row0 + 1, PS_MIN (inSource->pixels->row0 + inSource->pixels->numRows - 2, inSource->peak->y));
     84
     85            psPolynomial2D *bicube = psImageBicubeFit (inSource->pixels, ix, iy);
     86            psPlane min = psImageBicubeMin (bicube);
     87
     88            psTrace ("psphot", 5, "peak coord: %f %f -> %f %f\n",
     89                     modelEXT->params->data.F32[PM_PAR_XPOS], modelEXT->params->data.F32[PM_PAR_YPOS], min.x + ix, min.y + iy);
     90
     91            // if min point is too deviant, keep the old value
     92            if ((fabs(min.x) < 1.5) && (fabs(min.y) < 1.5)) {
     93                modelEXT->params->data.F32[PM_PAR_XPOS] = min.x + ix;
     94                modelEXT->params->data.F32[PM_PAR_YPOS] = min.y + iy;
     95            }
     96            psFree (bicube);
     97        }
     98
     99        // set PSF parameters for this model
     100        pmModel *model = pmModelFromPSF (modelEXT, psf);
     101        psFree (modelEXT);
     102
     103        // save the original coords
     104        x = model->params->data.F32[PM_PAR_XPOS];
     105        y = model->params->data.F32[PM_PAR_YPOS];
     106
     107        // set the fit radius based on the object flux limit and the model
     108        psphotCheckRadiusPSF (readout, inSource, model);
     109
     110        // make temporary copies of the image pixels and mask
     111        otSource->mask   = psImageCopy (NULL, inSource->mask,   PS_TYPE_U8);
     112        otSource->pixels = psImageCopy (NULL, inSource->pixels, PS_TYPE_F32);
     113        otSource->weight = psImageCopy (NULL, inSource->weight, PS_TYPE_F32);
     114
     115        // build the model image
     116        psImage *flux = otSource->pixels;
     117        psImage *mask = otSource->mask;
     118
     119        // set model to unit peak, zero sky (we assume sky is subtracted)
     120        model->params->data.F32[PM_PAR_SKY] = 0.0;
     121        model->params->data.F32[PM_PAR_I0] = 1.0;
     122
     123        // fill in the model pixel values
     124        psImageInit (flux, 0.0);
     125        psImageKeepCircle (mask, x, y, model->radiusTMP, "OR", PM_MASK_MARK);
     126        pmModelAdd (flux, mask, model, false, false);
     127
     128        // calculate nDOF (nPix - 1)
     129        // int Nmaskpix = psImageCountPixelMask (mask, allArray, PM_MASK_SAT);
     130        // model->nDOF  = mask->numCols*mask->numRows - Nmaskpix - 1;
     131
     132        // save source in list
     133        otSource->modelPSF = model;
     134        index->data.U32[models->n] = i;
     135        psArrayAdd (models, 100, otSource);
     136        psFree (otSource);
    137137    }
    138138    psLogMsg ("psphot.emsemble", 4, "built models: %f (%ld objects)\n", psTimerMark ("psphot"), sources->n);
    139    
     139
    140140    // fill out the sparse matrix
    141141    psSparse *sparse = psSparseAlloc (models->n, 100);
     
    144144
    145145    for (int i = 0; i < models->n; i++) {
    146         int N = index->data.U32[i];
    147         pmSource *Fi = sources->data[N];
    148         pmSource *Mi = models->data[i];
    149 
    150         // scale by diagonal element (auto-cross-product)
    151         r = pmSourceCrossProduct (Mi, Mi, CONSTANT_PHOTOMETRIC_WEIGHTS);
    152         weight->data.F32[i] = r;
    153 
    154         psSparseMatrixElement (sparse, i, i, 1.0);
    155 
    156         // find the image x model value
    157         f = pmSourceCrossProduct (Fi, Mi, CONSTANT_PHOTOMETRIC_WEIGHTS);
    158         psSparseVectorElement (sparse, i, f / r);
    159 
    160         // loop over all other stars following this one
    161         for (int j = i + 1; j < models->n; j++) {
    162             pmSource *Mj = models->data[j];
    163 
    164             // skip over disjoint source images, break after last possible overlap
    165             if (Mi->pixels->row0 + Mi->pixels->numRows < Mj->pixels->row0) break;
    166             if (Mj->pixels->row0 + Mj->pixels->numRows < Mi->pixels->row0) continue;
    167             if (Mi->pixels->col0 + Mi->pixels->numCols < Mj->pixels->col0) continue;
    168             if (Mj->pixels->col0 + Mj->pixels->numCols < Mi->pixels->col0) continue;
    169            
    170             // got an overlap; calculate cross-product and add to output array
    171             f = pmSourceCrossProduct (Mi, Mj, CONSTANT_PHOTOMETRIC_WEIGHTS);
    172             psSparseMatrixElement (sparse, j, i, f / r);
    173         }
     146        int N = index->data.U32[i];
     147        pmSource *Fi = sources->data[N];
     148        pmSource *Mi = models->data[i];
     149
     150        // scale by diagonal element (auto-cross-product)
     151        r = pmSourceCrossProduct (Mi, Mi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     152        weight->data.F32[i] = r;
     153
     154        psSparseMatrixElement (sparse, i, i, 1.0);
     155
     156        // find the image x model value
     157        f = pmSourceCrossProduct (Fi, Mi, CONSTANT_PHOTOMETRIC_WEIGHTS);
     158        psSparseVectorElement (sparse, i, f / r);
     159
     160        // loop over all other stars following this one
     161        for (int j = i + 1; j < models->n; j++) {
     162            pmSource *Mj = models->data[j];
     163
     164            // skip over disjoint source images, break after last possible overlap
     165            if (Mi->pixels->row0 + Mi->pixels->numRows < Mj->pixels->row0) break;
     166            if (Mj->pixels->row0 + Mj->pixels->numRows < Mi->pixels->row0) continue;
     167            if (Mi->pixels->col0 + Mi->pixels->numCols < Mj->pixels->col0) continue;
     168            if (Mj->pixels->col0 + Mj->pixels->numCols < Mi->pixels->col0) continue;
     169
     170            // got an overlap; calculate cross-product and add to output array
     171            f = pmSourceCrossProduct (Mi, Mj, CONSTANT_PHOTOMETRIC_WEIGHTS);
     172            psSparseMatrixElement (sparse, j, i, f / r);
     173        }
    174174    }
    175175    psLogMsg ("psphot.emsemble", 4, "built matrix: %f (%d elements)\n", psTimerMark ("psphot"), sparse->Nelem);
     
    186186    // adjust models, set sources and subtract
    187187    for (int i = 0; i < models->n; i++) {
    188         int N = index->data.U32[i];
    189         pmSource *Fi = sources->data[N];
    190         pmSource *Mi = models->data[i];
    191 
    192         // if we already have a PSF model, free it.
    193         psFree (Fi->modelPSF);
    194 
    195         // need to increment counter so we can free models here and sources above
    196         Fi->modelPSF = psMemIncrRefCounter (Mi->modelPSF);
    197 
    198         // assign linearly-fitted normalization
    199         if (isnan(norm->data.F32[i])) {
    200             psAbort ("psphot", "ensemble source is nan");
    201         }
    202         Fi->modelPSF->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
    203         Fi->modelPSF->dparams->data.F32[PM_PAR_I0] = sqrt(sqrt(2) * norm->data.F32[i] / (sparse->Bfj->data.F32[i] * weight->data.F32[i]));
    204         // XXX EAM : this factor of sqrt(2) makes the errors consistent, but I don't understand it
    205 
    206         // subtract object
    207         pmModelSub (Fi->pixels, Fi->mask, Fi->modelPSF, false, false);
    208         Fi->mode |= PM_SOURCE_MODE_SUBTRACTED;
    209         if (!final) Fi->mode |= PM_SOURCE_MODE_TEMPSUB;
     188        int N = index->data.U32[i];
     189        pmSource *Fi = sources->data[N];
     190        pmSource *Mi = models->data[i];
     191
     192        // if we already have a PSF model, free it.
     193        psFree (Fi->modelPSF);
     194
     195        // need to increment counter so we can free models here and sources above
     196        Fi->modelPSF = psMemIncrRefCounter (Mi->modelPSF);
     197
     198        // assign linearly-fitted normalization
     199        if (isnan(norm->data.F32[i])) {
     200            psAbort ("psphot", "ensemble source is nan");
     201        }
     202        Fi->modelPSF->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
     203        Fi->modelPSF->dparams->data.F32[PM_PAR_I0] = sqrt(sqrt(2) * norm->data.F32[i] / (sparse->Bfj->data.F32[i] * weight->data.F32[i]));
     204        // XXX EAM : this factor of sqrt(2) makes the errors consistent, but I don't understand it
     205
     206        // subtract object
     207        pmModelSub (Fi->pixels, Fi->mask, Fi->modelPSF, false, false);
     208        Fi->mode |= PM_SOURCE_MODE_SUBTRACTED;
     209        if (!final) Fi->mode |= PM_SOURCE_MODE_TEMPSUB;
    210210    }
    211211
    212212    // measure chisq for each source
    213213    for (int i = 0; final && (i < models->n); i++) {
    214         int N = index->data.U32[i];
    215         pmSource *Fi = sources->data[N];
    216         pmModel *model = Fi->modelPSF;
    217 
    218         x = model->params->data.F32[PM_PAR_XPOS];
    219         y = model->params->data.F32[PM_PAR_YPOS];
    220 
    221         psImageKeepCircle (Fi->mask, x, y, model->radiusTMP, "OR", PM_MASK_MARK);
    222         pmSourceChisq (model, Fi->pixels, Fi->mask, Fi->weight);
    223         psImageKeepCircle (Fi->mask, x, y, model->radiusTMP, "AND", NOT_U8(PM_MASK_MARK));
     214        int N = index->data.U32[i];
     215        pmSource *Fi = sources->data[N];
     216        pmModel *model = Fi->modelPSF;
     217
     218        x = model->params->data.F32[PM_PAR_XPOS];
     219        y = model->params->data.F32[PM_PAR_YPOS];
     220
     221        psImageKeepCircle (Fi->mask, x, y, model->radiusTMP, "OR", PM_MASK_MARK);
     222        pmSourceChisq (model, Fi->pixels, Fi->mask, Fi->weight);
     223        psImageKeepCircle (Fi->mask, x, y, model->radiusTMP, "AND", PS_NOT_U8(PM_MASK_MARK));
    224224    }
    225225
     
    239239    int Npix = 0;
    240240    for (int j = 0; j < image->numRows; j++) {
    241         for (int i = 0; i < image->numCols; i++) {
    242             if (mask->data.U8[j][i]) continue;
    243             if (weight->data.F32[j][i] <= 0) continue;
    244             dC += PS_SQR (image->data.F32[j][i]) / weight->data.F32[j][i];
    245             Npix ++;
    246         }
     241        for (int i = 0; i < image->numCols; i++) {
     242            if (mask->data.U8[j][i]) continue;
     243            if (weight->data.F32[j][i] <= 0) continue;
     244            dC += PS_SQR (image->data.F32[j][i]) / weight->data.F32[j][i];
     245            Npix ++;
     246        }
    247247    }
    248248    model->nDOF = Npix - 1;
Note: See TracChangeset for help on using the changeset viewer.