IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14919


Ignore:
Timestamp:
Sep 20, 2007, 10:48:31 AM (19 years ago)
Author:
eugene
Message:

added capability to iterate over ApResid trend scales to choose the best, measuring systematic error

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branch_20070830/psphot/src/psphotApResid.c

    r14786 r14919  
    5151
    5252    psVector *mask    = psVectorAllocEmpty (300, PS_TYPE_U8);
     53    psVector *mag     = psVectorAllocEmpty (300, PS_TYPE_F32);
    5354    psVector *xPos    = psVectorAllocEmpty (300, PS_TYPE_F32);
    5455    psVector *yPos    = psVectorAllocEmpty (300, PS_TYPE_F32);
     
    5657    psVector *dMag    = psVectorAllocEmpty (300, PS_TYPE_F32);
    5758    Npsf = 0;
    58 
    59     FILE *dumpFile = NULL;
    60     if (psTraceGetLevel("psphot") >= 5) {
    61         dumpFile = fopen ("apresid.dat", "w");
    62     }
    6359
    6460    // select all good PM_SOURCE_TYPE_STAR entries
     
    9490        }
    9591
     92        mag->data.F32[Npsf]     = source->psfMag;
    9693        apResid->data.F32[Npsf] = dap;
    9794        xPos->data.F32[Npsf]    = model->params->data.F32[PM_PAR_XPOS];
     
    10198
    10299        dMag->data.F32[Npsf] = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
    103 
    104         if (psTraceGetLevel("psphot") >= 5) {
    105             fprintf (dumpFile, "%f %f  %f %f %f  %x\n",
    106                      xPos->data.F32[Npsf], yPos->data.F32[Npsf],
    107                      source->psfMag, dMag->data.F32[Npsf], apResid->data.F32[Npsf],
    108                      mask->data.U8[Npsf]);
    109         }
    110100
    111101        psVectorExtend (mask,    100, 1);
     
    116106        Npsf ++;
    117107    }
    118 
    119     if (psTraceGetLevel("psphot") >= 5) {
    120         fclose (dumpFile);
    121     }
    122108   
    123109    psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "measure aperture residuals for %d objects (%d skipped, %d failed, %ld invalid)\n",
     
    134120    // XXX is this asymmetric clipping still needed?  this analysis should come after neighbors are subtracted...
    135121    // 3hi/1lo sigma clipping on the rflux vs metric fit
    136     psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN);
    137     stats->min = 2.0;
    138     stats->max = 3.0;
    139 
    140     // XXX set the pmTrend2D mode, nXtrend, nYtrend based on the user inputs
    141     // XXX psf->ApTrend = pmTrend2DAlloc (mode, readout->image->numCols, readout->image->numRows, nXtrend, nYtrend, stats);
    142 
    143     psf->ApTrend = pmTrend2DAlloc (PM_TREND_MAP, readout->image, 5, 5, stats);
    144     pmTrend2DFit (psf->ApTrend, xPos, yPos, apResid, dMag);
    145    
     122    // systematic error information
     123    float errorScale = 0.0;
     124    float errorFloor = 0.0;
     125
     126    float errorFloorMin = FLT_MAX;
     127    int entryMin = -1;
     128
     129    // *** iterate over spatial scale until error Floor increases
     130    // *** fit out the dap vs mag trend?
     131    // *** stop if Npsf / (Nx * Ny) < 3
     132    for (int i = 1; i < 10; i++) {
     133
     134        if (!psphotApResidTrend (readout, psf, Npsf, i, &errorScale, &errorFloor, mask, xPos, yPos, apResid, dMag)) {
     135            break;
     136        }
     137
     138        // store the resulting errorFloor values and the scales, redo the best
     139        if (errorFloor < errorFloorMin) {
     140            errorFloorMin = errorFloor;
     141            entryMin = i;
     142        }
     143    }
     144    if (entryMin == -1) {
     145        psAbort ("failed on ApResid Trend");
     146    }
     147
     148    psphotApResidTrend (readout, psf, Npsf, entryMin, &errorScale, &errorFloor, mask, xPos, yPos, apResid, dMag);
     149
     150    // construct the fitted values and the residuals
     151    psVector *apResidFit = pmTrend2DEvalVector (psf->ApTrend, xPos, yPos);
     152    psVector *apResidRes = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) apResidFit);
     153    psVector *dMagSys = (psVector *) psBinaryOp (NULL, (void *) dMag, "*", (void *) psScalarAlloc(errorScale, PS_TYPE_F32));
     154
    146155    psphotSaveImage (NULL, psf->ApTrend->map->map, "apresid.map.fits");
    147156
    148     // construct the fitted values and the residuals
    149     psVector *fit   = pmTrend2DEvalVector (psf->ApTrend, xPos, yPos);
    150     psVector *resid = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) fit);
    151 
    152     // measure scatter for sources with dMag < 0.01 (S/N = 100)
    153     int Nkeep = 0;
    154     psStats *residStats = psStatsAlloc (PS_STAT_SAMPLE_STDEV);
    155     for (int i = 0; i < dMag->n; i++) {
    156         if (dMag->data.F32[i] > 0.01) {
    157             mask->data.U8[i] |= 0x02;
    158         }
    159         if (! mask->data.U8[i]) Nkeep ++;
    160     }
    161     psVectorStats (residStats, resid, NULL, mask, 0x03);
     157    if (psTraceGetLevel("psphot") >= 5) {
     158        FILE *dumpFile = fopen ("apresid.dat", "w");
     159        for (int i = 0; i < xPos->n; i++) {
     160            fprintf (dumpFile, "%f %f  %f %f %f  %f %f  %x\n",
     161                     xPos->data.F32[i], yPos->data.F32[i],
     162                     mag->data.F32[i], dMag->data.F32[i], dMagSys->data.F32[i],
     163                     apResid->data.F32[i], apResidRes->data.F32[i],
     164                     mask->data.U8[i]);
     165        }
     166        fclose (dumpFile);
     167    }
    162168
    163169    // apply ApTrend results
    164     psf->ApResid  = pmTrend2DEval (psf->ApTrend, 0.0, 0.0); // XXX use chip center?
    165     psf->dApResid = residStats->sampleStdev;
     170    float xc = 0.5*readout->image->numCols + readout->image->col0 + 0.5;
     171    float yc = 0.5*readout->image->numRows + readout->image->row0 + 0.5;
     172    psf->ApResid  = pmTrend2DEval (psf->ApTrend, xc, yc); // ap-fit at chip center
     173    psf->dApResid = errorFloor;
    166174    psf->nApResid = Npsf;
    167175
     
    174182    psMetadataAdd (recipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "ap residual scatter", psf->nApResid);
    175183
    176     psLogMsg ("psphot.apresid", PS_LOG_INFO, "measure full-frame aperture residuals for %d of %d objects: %f sec\n", Nkeep, Npsf, psTimerMark ("psphot"));
     184    // psLogMsg ("psphot.apresid", PS_LOG_INFO, "measure full-frame aperture residuals for %d of %d objects: %f sec\n", Nkeep, Npsf, psTimerMark ("psphot"));
    177185    psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "aperture residual: %f +/- %f\n", psf->ApResid, psf->dApResid);
    178186
     187    psFree (mag);
    179188    psFree (mask);
    180189    psFree (xPos);
     
    183192    psFree (dMag);
    184193
    185     psFree (fit);
    186     psFree (resid);
    187     psFree (stats);
    188     psFree (residStats);
    189194    return true;
    190195}
     
    196201*/
    197202
     203bool psphotMagErrorScale (float *errorScale, float *errorFloor, psVector *dMag, psVector *dap, int nGroup) {
     204
     205    psStats *statsS = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     206    psStats *statsM = psStatsAlloc (PS_STAT_SAMPLE_MEAN);
     207
     208    // measure the trend in bins with 10 values each; if < 10 total, use them all
     209    int nBin = PS_MAX (dMag->n / nGroup, 1);
     210
     211    // output vectors for ApResid trend
     212    psVector *dSo = psVectorAlloc (nBin, PS_TYPE_F32);
     213    psVector *dMo = psVectorAlloc (nBin, PS_TYPE_F32);
     214    psVector *dRo = psVectorAlloc (nBin, PS_TYPE_F32);
     215
     216    // use dMag to group the dMag and dap vectors
     217    psVector *index = psVectorSortIndex (NULL, dMag);
     218
     219    // subset vectors for dMag and dap values within the given range
     220    psVector *dMSubset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);
     221    psVector *dASubset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);
     222
     223    int n = 0;
     224    for (int i = 0; i < dMo->n; i++) {
     225        int j;
     226        for (j = 0; (j < nGroup) && (n < dMag->n); j++, n++) {
     227            int N = index->data.U32[n];
     228            dMSubset->data.F32[j] = dMag->data.F32[N];
     229            dASubset->data.F32[j] = dap->data.F32[N];
     230        }
     231        dMSubset->n = j;
     232        dASubset->n = j;
     233
     234        psStatsInit (statsS);
     235        psStatsInit (statsM);
     236
     237        psVectorStats (statsS, dASubset, NULL, NULL, 0xff);
     238        psVectorStats (statsM, dMSubset, NULL, NULL, 0xff);
     239
     240        dSo->data.F32[i] = statsS->robustStdev;
     241        dMo->data.F32[i] = statsM->sampleMean;
     242
     243        dRo->data.F32[i] = statsS->robustStdev / statsM->sampleMean;
     244    }
     245    psFree (dMSubset);
     246    psFree (dASubset);
     247   
     248    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     249    psVectorStats (stats, dRo, NULL, NULL, 0);
     250
     251    *errorScale = stats->sampleMedian;
     252    *errorFloor = dSo->data.F32[0];
     253
     254    psFree (stats);
     255    psFree (index);
     256
     257    psFree (dRo);
     258    psFree (dMo);
     259    psFree (dSo);
     260   
     261    psFree (statsS);
     262    psFree (statsM);
     263
     264    return true;
     265}
     266
     267bool psphotApResidTrend (pmReadout *readout, pmPSF *psf, int Npsf, int scale, float *errorScale, float *errorFloor, psVector *mask, psVector *xPos, psVector *yPos, psVector *apResid, psVector *dMag) {
     268
     269    int Nx, Ny;
     270       
     271    psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     272    stats->min = 2.0;
     273    stats->max = 3.0;
     274
     275    if (readout->image->numCols > readout->image->numRows) {
     276        Nx = scale;
     277        Ny = PS_MAX (1, Nx * (readout->image->numRows / readout->image->numCols));
     278    } else {
     279        Ny = scale;
     280        Nx = PS_MAX (1, Ny * (readout->image->numCols / readout->image->numRows));
     281    }
     282
     283    if (Npsf < 3*Nx*Ny) {
     284        return false;
     285    }
     286
     287    // measure Trend2D for the current spatial scale
     288    psFree (psf->ApTrend);
     289    psf->ApTrend = pmTrend2DAlloc (PM_TREND_MAP, readout->image, Nx, Ny, stats);
     290    pmTrend2DFit (psf->ApTrend, mask, 0xff, xPos, yPos, apResid, dMag);
     291   
     292    // construct the fitted values and the residuals
     293    psVector *apResidFit = pmTrend2DEvalVector (psf->ApTrend, xPos, yPos);
     294    psVector *apResidRes = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) apResidFit);
     295
     296    // measure systematic errorFloor & systematic / photon scale factor
     297    // XXX this is a bit arbitrary, but it forces ~3 stars from the bright bin per spatial bin
     298    int nGroup = PS_MAX (3*Nx*Ny, 10);
     299    psphotMagErrorScale (errorScale, errorFloor, dMag, apResidRes, nGroup);
     300
     301    psLogMsg ("psphot.apresid", PS_LOG_INFO, "result of %d x %d grid (%d stars per bin)\n", Nx, Ny, nGroup);
     302    psLogMsg ("psphot.apresid", PS_LOG_INFO, "systematic error / photon error: %f\n", *errorScale);
     303    psLogMsg ("psphot.apresid", PS_LOG_INFO, "systematic scatter floor: %f\n", *errorFloor);
     304
     305    psFree (stats);
     306    psFree (apResidFit);
     307    psFree (apResidRes);
     308
     309    return true;
     310}
     311   
Note: See TracChangeset for help on using the changeset viewer.