IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 3, 2013, 2:43:13 PM (13 years ago)
Author:
eugene
Message:

thread psphotModelBackground, psphotAddOrSubNoise, psphotGuessModel; add recipe options to control selection of extended models fitted; iterate on the trail window a bit

Location:
trunk/psphot
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src

  • trunk/psphot/src/psphotModelBackground.c

    r34528 r35769  
    2828}
    2929
     30// track background cell failures for log reporting purposes
     31static int nFailures = 0;
    3032
    3133// Generate the background model
     
    3335// linear interpolation to generate full-scale model
    3436//
    35 // NOTE that the 'analysis' metedata pass in here is used to store the binning information.
     37// NOTE that the 'analysis' metedata passed in here is used to store the binning information.
    3638// This may be the analysis for this readout, but it may be the analysis for the pmFPAfile
    3739// corresponding to the model.  Other information about the background model is saved on the
     
    109111
    110112    const psStatsOptions statsOption = statsOptionLocation | statsOptionWidth;
    111     psStats *stats = psStatsAlloc (statsOption);
     113    psStats *statsDefaults = psStatsAlloc (statsOption);
    112114
    113115    // set range for old-version of sky statistic
    114116    if (statsOptionLocation & PS_STAT_ROBUST_QUARTILE) {
    115         stats->min = 0.25;
    116         stats->max = 0.75;
     117        statsDefaults->min = 0.25;
     118        statsDefaults->max = 0.75;
    117119    }
    118120
    119121    // set user-option for number of pixels per region
    120     stats->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX");
     122    statsDefaults->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX");
    121123    if (!status) {
    122         stats->nSubsample = 1000;
     124        statsDefaults->nSubsample = 1000;
    123125    }
    124126
    125127    // optionally set the binsize
    126     stats->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS");
     128    statsDefaults->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS");
    127129    if (status) {
    128         stats->options |= PS_STAT_USE_BINSIZE;
     130        statsDefaults->options |= PS_STAT_USE_BINSIZE;
    129131    }
    130132
    131133    // optionally set the sigma clipping
    132     stats->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA");
     134    statsDefaults->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA");
    133135    if (!status) {
    134         if (stats->options & PS_STAT_FITTED_MEAN) {
    135             stats->clipSigma = 1.0;
     136        if (statsDefaults->options & PS_STAT_FITTED_MEAN) {
     137            statsDefaults->clipSigma = 1.0;
    136138        } else {
    137             stats->clipSigma = 3.0;
     139            statsDefaults->clipSigma = 3.0;
    138140        }
    139141    }
    140 
    141     // stats is not initialized by psStats???  use this to save the input options
    142     // XXX re-work this to use the new psStatsInit function
    143     psStats *statsDefaults = psStatsAlloc (statsOption);
    144     *statsDefaults = *stats;
    145142
    146143    // we save the binning structure for use in psphotMagnitudes
     
    154151
    155152    // XXXX we can thread this here by running blocks in parallel
    156 
    157     int nFailures = 0;
    158153    psImageBackgroundInit();
     154    nFailures = 0; // reset for this pass
    159155
    160156    // we have Nx * Ny model points, but we can use a window which is larger (or smaller) than
     
    163159
    164160    // measure clipped median for subimages
    165     psRegion ruffRegion = psRegionSet (0,0,0,0);
    166     psRegion fineRegion = psRegionSet (0,0,0,0);
    167161    for (int iy = 0; iy < model->numRows; iy++) {
    168162        for (int ix = 0; ix < model->numCols; ix++) {
    169 
    170             // convert the ruff grid cell to the equivalent fine grid cell
    171             ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample,
    172                                       iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample);
    173             fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
    174             fineRegion = psRegionForImage (image, fineRegion);
    175 
    176             psImage *subset  = psImageSubset (image, fineRegion);
    177             if (!subset->numCols || !subset->numRows) {
    178                 psFree (subset);
    179                 continue;
     163           
     164            // allocate a job -- if threads are not defined, this just runs the job
     165            psThreadJob *job = psThreadJobAlloc ("PSPHOT_MODEL_BACKGROUND");
     166
     167            psArrayAdd(job->args, 1, image);
     168            psArrayAdd(job->args, 1, mask);
     169            psArrayAdd(job->args, 1, binning);
     170            psArrayAdd(job->args, 1, rng);
     171            psArrayAdd(job->args, 1, statsDefaults);
     172
     173            psArrayAdd(job->args, 1, modelData);
     174            psArrayAdd(job->args, 1, modelStdevData);
     175
     176            PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
     177
     178            PS_ARRAY_ADD_SCALAR(job->args, ix, PS_TYPE_S32);
     179            PS_ARRAY_ADD_SCALAR(job->args, iy, PS_TYPE_S32);
     180
     181            PS_ARRAY_ADD_SCALAR(job->args, dXsample, PS_TYPE_F32);
     182            PS_ARRAY_ADD_SCALAR(job->args, dYsample, PS_TYPE_F32);
     183
     184            PS_ARRAY_ADD_SCALAR(job->args, statsOptionLocation, PS_TYPE_S32);
     185            PS_ARRAY_ADD_SCALAR(job->args, statsOptionWidth, PS_TYPE_S32);
     186
     187            PS_ARRAY_ADD_SCALAR(job->args, NAN, PS_TYPE_F32); // this is used as a return value for dQvalue
     188
     189# if (1)
     190            if (!psThreadJobAddPending(job)) {
     191                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     192                return NULL;
    180193            }
    181             psImage *submask = psImageSubset (mask, fineRegion);
    182 
    183             // reset the default values
    184             *stats = *statsDefaults;
    185 
    186             // Use the selected background statistic for the first pass
    187             // If it fails, fall back on the "ROBUST_MEDIAN" version
    188             // If both fail, set the pixel to NAN and (below) interpolate
    189             // XXX psImageBackground will probably be renamed psImageStats
    190             // XXX don't bother trying if there are no valid pixels...
    191 
    192             psVector *sample = NULL;
    193 
    194             // turn on stats tracing in desired cells
    195             # if (0)
    196             psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS");
    197             assert (plots);
    198 
    199             int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X");
    200             assert (status);
    201             int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y");
    202             assert (status);
    203 
    204             bool gotX = (xPlot < 0) || (xPlot == ix);
    205             bool gotY = (yPlot < 0) || (yPlot == iy);
    206 
    207             if (gotX && gotY) {
    208                 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6);
    209                 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6);
    210             } else {
    211                 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0);
    212                 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0);
     194# else
     195            if (!psphotModelBackground_Threaded(job)) {
     196                psError(PS_ERR_UNKNOWN, false, "Failure to model background.");
     197                return NULL;
    213198            }
    214             # endif
    215 
    216             if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
    217                 if (stats->options & PS_STAT_ROBUST_QUARTILE) {
    218                     modelData[iy][ix] = stats->robustMedian;
    219                 } else {
    220                     modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation);
    221                 }
    222                 modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth);
    223                 // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
    224                 psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
    225 
    226                 // supply sample to plotting routing
    227                 psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
    228             } else {
    229                 psStatsOptions currentOptions = stats->options;
    230                 stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV;
    231                 if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
    232                     if ((nFailures < 3) || (nFailures % 100 == 0)) {
    233                         psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for "
    234                                   "(%dx%d, (row0,col0) = (%d,%d)",
    235                                   subset->numRows, subset->numCols, subset->row0, subset->col0);
    236                     }
    237                     nFailures ++;
    238                     modelData[iy][ix] = modelStdevData[iy][ix] = NAN;
    239                 } else {
    240                     modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN);
    241                     modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV);
    242 
    243                     // supply sample to plotting routing
    244                     psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
    245                 }
    246                 // drop errors caused by psImageBackground failures
    247                 // XXX we probably should trap and exit on serious failures
    248                 psErrorClear();
    249                 stats->options = currentOptions;
    250             }
    251             psFree(sample);
    252             modelData[iy][ix] += SKY_BIAS;
    253             psFree (subset);
    254             psFree (submask);
     199            if (job->args->n < 1) {
     200                fprintf (stderr, "error with job\n");
     201            } else {
     202                psScalar *scalar = job->args->data[14];
     203                float dQvalue = scalar->data.F32;
     204                psVectorAppend (dQ, dQvalue);
     205            }
     206            psFree(job);
     207# endif
    255208        }
     209    }
     210
     211    // wait for the threads to finish and manage results
     212    if (!psThreadPoolWait (false, true)) {
     213        psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     214        return NULL;
     215    }
     216
     217    // we have only supplied one type of job, so we can assume the types here
     218    psThreadJob *job = NULL;
     219    while ((job = psThreadJobGetDone()) != NULL) {
     220        if (job->args->n < 1) {
     221            fprintf (stderr, "error with job\n");
     222        } else {
     223            psScalar *scalar = job->args->data[14];
     224            float dQvalue = scalar->data.F32;
     225            psVectorAppend (dQ, dQvalue);
     226        }
     227        psFree(job);
    256228    }
    257229
     
    302274    if (Count == 0) {
    303275        psError (PSPHOT_ERR_DATA, true, "failed to build background image");
    304         psFree(stats);
    305276        psFree(statsDefaults);
    306277        psFree(binning);
     
    318289            modelData[iy][ix] = Value;
    319290            modelStdevData[iy][ix] = ValueStdev;
     291        }
     292    }
     293
     294    // apply artificial offset if desired
     295    for (int iy = 0; iy < model->numRows; iy++) {
     296        for (int ix = 0; ix < model->numCols; ix++) {
     297            modelData[iy][ix] += SKY_BIAS;
    320298        }
    321299    }
     
    364342    psFree(dQ);
    365343
    366     psFree(stats);
    367344    psFree(statsDefaults);
    368345    psFree(binning);
     
    433410    return true;
    434411}
     412
     413bool psphotModelBackground_Threaded (psThreadJob *job) {
     414
     415    psImage *image          = job->args->data[0];
     416    psImage *mask           = job->args->data[1];
     417
     418    psImageBinning *binning = job->args->data[2];
     419
     420    psRandom *rng           = job->args->data[3];
     421    psStats *statsDefaults  = job->args->data[4];
     422
     423    psF32 **modelData       = job->args->data[5];
     424    psF32 **modelStdevData  = job->args->data[6];
     425
     426    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[7],PS_TYPE_IMAGE_MASK_DATA);
     427
     428    int ix                  = PS_SCALAR_VALUE(job->args->data[8],S32);
     429    int iy                  = PS_SCALAR_VALUE(job->args->data[9],S32);
     430
     431    float dXsample          = PS_SCALAR_VALUE(job->args->data[10],F32);
     432    float dYsample          = PS_SCALAR_VALUE(job->args->data[11],F32);
     433
     434    psStatsOptions statsOptionLocation = PS_SCALAR_VALUE(job->args->data[12],S32);
     435    psStatsOptions statsOptionWidth    = PS_SCALAR_VALUE(job->args->data[13],S32);
     436
     437    // convert the ruff grid cell to the equivalent fine grid cell
     438    psRegion ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample, iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample);
     439    psRegion fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
     440    fineRegion = psRegionForImage (image, fineRegion);
     441
     442    psImage *subset  = psImageSubset (image, fineRegion);
     443    if (!subset->numCols || !subset->numRows) {
     444        psFree (subset);
     445        return false; // XXX do we / should we fail on this?
     446    }
     447    psImage *submask = psImageSubset (mask, fineRegion);
     448
     449    psStats *stats = psStatsAlloc (PS_STAT_NONE);
     450    *stats = *statsDefaults;
     451
     452    // Use the selected background statistic for the first pass
     453    // If it fails, fall back on the "ROBUST_MEDIAN" version
     454    // If both fail, set the pixel to NAN and (later) interpolate
     455
     456    psVector *sample = NULL;
     457    float dQvalue = NAN;
     458
     459    if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
     460        if (stats->options & PS_STAT_ROBUST_QUARTILE) {
     461            modelData[iy][ix] = stats->robustMedian;
     462        } else {
     463            modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation);
     464        }
     465        modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth);
     466
     467        // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
     468        // XXX this operation is not thread safe -- move out somehow...
     469        // psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian);
     470        dQvalue = stats->robustUQ + stats->robustLQ - 2*stats->robustMedian;
     471        // return dQvalue to main thread
     472
     473        // supply sample to plotting routing
     474        // only allow in a non-threaded context -- can plot more than one cell
     475        // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
     476    } else {
     477        // psStatsOptions currentOptions = stats->options;
     478        stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV;
     479        if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) {
     480            if ((nFailures < 3) || (nFailures % 100 == 0)) {
     481                psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for "
     482                          "(%dx%d, (row0,col0) = (%d,%d)",
     483                          subset->numRows, subset->numCols, subset->row0, subset->col0);
     484            }
     485            nFailures ++; // static
     486            modelData[iy][ix] = modelStdevData[iy][ix] = NAN;
     487        } else {
     488            modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN);
     489            modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV);
     490
     491            // supply sample to plotting routing
     492            // only allow in a non-threaded context -- can plot more than one cell
     493            // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample);
     494        }
     495        // drop errors caused by psImageBackground failures
     496        // NOTE : psStats raises errors when it cannot find a solution; this
     497        // probably should not be errors but exit stats info only, but c'est la code
     498        // XXX we probably should trap and exit on serious failures
     499        psErrorClear();
     500        // stats->options = currentOptions; // this is not needed (set by init above)
     501    }
     502    psFree (stats);
     503    psFree (sample);
     504    psFree (subset);
     505    psFree (submask);
     506
     507    // return the dQvalue to the calling thread
     508    psScalar *scalar = job->args->data[14];
     509    scalar->data.F32 = dQvalue;
     510
     511    return true;
     512}
     513
     514// code for in-line plotting from above
     515// turn on stats tracing in desired cells
     516// XXX this code may need to be re-worked for a threaded context
     517# if (0)
     518    psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS");
     519    assert (plots);
     520
     521    int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X");
     522    assert (status);
     523    int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y");
     524    assert (status);
     525
     526    bool gotX = (xPlot < 0) || (xPlot == ix);
     527    bool gotY = (yPlot < 0) || (yPlot == iy);
     528
     529    if (gotX && gotY) {
     530        (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6);
     531        (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6);
     532    } else {
     533        (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0);
     534        (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0);
     535    }
     536# endif
Note: See TracChangeset for help on using the changeset viewer.