IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 13, 2009, 4:50:10 PM (17 years ago)
Author:
eugene
Message:

add function to report on systematic errors; measure sys errors for ap resid, adjust comments a bit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715/psModules/src/objects/pmPSFtry.c

    r25303 r25352  
    245245        source->modelPSF->radiusFit = options->radius;
    246246
     247        // XXXX use a different radius for the aperture magnitude than for the PSF fit?
     248
    247249        // set object mask to define valid pixels
    248250        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->radius, "OR", markVal);
     
    422424              psStatsGetValue(options->stats, stdevStat), psfTry->sources->n);
    423425
    424 
     426    float dSys = psVectorSystematicError (psfTry->metric, psfTry->metricErr, 0.1);
     427    fprintf (stderr, "systematic error: %f\n", dSys);
     428
     429    int n = 0;
     430    psVector *bright = psVectorAllocEmpty (psfTry->metric->n, PS_TYPE_F32);
     431    psVector *brightErr = psVectorAllocEmpty (psfTry->metric->n, PS_TYPE_F32);
     432    for (int i = 0; i < psfTry->metric->n; i++) {
     433        if (!isfinite(psfTry->metric->data.F32[i])) continue;
     434        if (!isfinite(psfTry->metricErr->data.F32[i])) continue;
     435        if (psfTry->metricErr->data.F32[i] <= 0.0) continue;
     436        if (psfTry->metricErr->data.F32[i] > 0.005) continue;
     437        bright->data.F32[n] = psfTry->metric->data.F32[i];
     438        brightErr->data.F32[n] = psfTry->metricErr->data.F32[i];
     439        n++;
     440    }
     441    bright->n = brightErr->n = n;
     442
     443    float dSysBright = psVectorSystematicError (bright, brightErr, 0.1);
     444    fprintf (stderr, "bright systematic error: %f\n", dSysBright);
    425445
    426446    // XXX test dump of fitted model (dump when tracing?)
     
    582602}
    583603
    584 
    585604bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask) {
    586605
     
    596615    // parameters, with the constraint that the minor axis must be greater than a minimum
    597616    // threshold.
     617
     618    // XXX re-read the sextractor manual on handling 'infinitely thin' sources...
    598619
    599620    // convert the measured source shape paramters to polarization terms
     
    10691090    return true;
    10701091}
     1092
     1093float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction) {
     1094
     1095    psAssert(residuals, "residuals cannot be NULL");
     1096    psAssert(errors, "errors cannot be NULL");
     1097    psAssert(residuals->n == errors->n, "residuals and errors must be the same length");
     1098
     1099    // given a vector of residuals and their formal errors, calculated the necessary systematic
     1100    // error needed to yield a reduced chisq of 1.0, after first tossing out the clipFraction
     1101    // highest chi-square contributors (allowed outliers)
     1102
     1103    psVector *mask  = psVectorAlloc(residuals->n, PS_TYPE_VECTOR_MASK);
     1104    psVector *chisq = psVectorAlloc(residuals->n, PS_TYPE_F32);
     1105
     1106    // calculate the chisq vector:
     1107    int Ngood = 0;
     1108    for (int i = 0; i < residuals->n; i++) {
     1109        chisq->data.F32[i] = PS_MAX_F32;
     1110        if (!isfinite(residuals->data.F32[i])) continue;
     1111        if (!isfinite(errors->data.F32[i])) continue;
     1112        if (errors->data.F32[i] <= 0.0) continue;
     1113        chisq->data.F32[i] = PS_SQR(residuals->data.F32[i] / errors->data.F32[i]);
     1114        Ngood ++;
     1115    }
     1116
     1117    psVector *index = psVectorSortIndex(NULL, chisq);
     1118
     1119    // toss out the clipFraction highest chisq values
     1120    for (int i = 0; i < residuals->n; i++) {
     1121        int n = index->data.S32[i];
     1122        if (i < (1.0 - clipFraction)*Ngood) {
     1123            mask->data.PS_TYPE_VECTOR_MASK_DATA[n] = 0;
     1124        } else {
     1125            mask->data.PS_TYPE_VECTOR_MASK_DATA[n] = 1;
     1126        }
     1127    }
     1128
     1129    // Ndof ~= Ngood
     1130    // Chisq_Ndof = sum(residuals_i^2 / error_i^2) / Ndof
     1131    // choose S2 such than Chisq^sys_Ndof = sum(residuals_i^2 / (error_i^2 + S2)) / Ndof = 1.0
     1132   
     1133    // use Newton-Raphson to solve for S2:
     1134
     1135    // use median sigma to calculate the initial guess for S2:
     1136    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
     1137    psVectorStats (stats, errors, NULL, mask, 1);
     1138    float errorMedian = stats->sampleMedian;
     1139   
     1140    float nPts = 0.0;
     1141    float res2mean = 0.0;
     1142    float ChiSq = 0.0;
     1143    for (int i = 0; i < residuals->n; i++) {
     1144        int n = index->data.S32[i];
     1145        if (mask->data.PS_TYPE_VECTOR_MASK_DATA[n]) continue;
     1146        res2mean += PS_SQR(residuals->data.F32[n]);
     1147        ChiSq += PS_SQR(residuals->data.F32[n] / errors->data.F32[n]);
     1148        nPts += 1.0;
     1149    }
     1150    res2mean /= nPts;
     1151    ChiSq /= nPts;
     1152   
     1153    float S2guess = res2mean - PS_SQR(errorMedian);
     1154
     1155    psLogMsg ("psModules", 3, "ChiSquare: %f, Ntotal: %ld, Ngood: %d, Nkeep: %.0f, S2 guess: %f\n",
     1156              ChiSq, residuals->n, Ngood, nPts, S2guess);
     1157
     1158    for (int iter = 0; iter < 10; iter++) {
     1159
     1160        ChiSq = 0.0;
     1161        float dRdS = 0.0;
     1162        for (int i = 0; i < residuals->n; i++) {
     1163            int n = index->data.S32[i];
     1164            if (mask->data.PS_TYPE_VECTOR_MASK_DATA[n]) continue;
     1165            float error2 = PS_SQR(errors->data.F32[n]) + S2guess;
     1166            ChiSq += PS_SQR(residuals->data.F32[n]) / error2;
     1167            dRdS += PS_SQR(residuals->data.F32[n]) / PS_SQR(error2);
     1168        }
     1169        ChiSq /= nPts;
     1170        dRdS /= nPts;
     1171
     1172        // Note the sign on dS: dRdS above is -1 * dR/dS formally
     1173        float dS = (ChiSq - 1.0) / dRdS;
     1174        S2guess += dS;
     1175
     1176        psLogMsg ("psModules", 3, "ChiSquare: %f, dS: %f, S2 guess: %f\n", ChiSq, dS, S2guess);
     1177    }
     1178
     1179    // free local allocations
     1180    return (sqrt(S2guess));
     1181}
     1182
Note: See TracChangeset for help on using the changeset viewer.