IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 6, 2011, 1:32:31 PM (15 years ago)
Author:
eugene
Message:
  • clarified the output to show the stages and their timing more clearly
  • psphotStackReadout now uses the same functions as psphotReadout (deprecated FitLinearStack, ExtendedAnalysisByObject, RadialAnalysisByObject, etc)
  • psphotStack now does 2nd (5 sigma) detection pass and radial photometry of the un-matched image (as well as the matched images)
  • for speed, fitting uses a smaller subset of pixels than subtraction: the model is extended when the subtraction is performed to avoid a discontinuity
  • extended source analysis (petrosians) is threaded
  • iterative kron radius / magnitude analysis with down-weighted neighbors replaces the masked neighbor kron analysis. the result of this analysis is used by fitting guesses and is the value written to the PSF and XFIT tables.
  • the target matched PSFs are determined in advance and the 0 element of this array is always the unmatched image (with target PSF of NAN)
  • dQ, the difference between the upper and lower quartile, is measured (but not yet used to adjust the sky level. sky should be FITTED_MEAN - 2.5*dQ
  • fake sources inserted for the efficiency analysis are removed at the end of the analysis
  • radial apertures is now threaded
  • edge case petrosian mags are now handled without aborts (may still have a problem with the measured error of the petrosian radius)
  • new sersic model guess based on the psf size, the moments, and the kron flux. the psf - kron mag is used to guess the index, then the index is used to convert measured moments into model guess parameters. this uses empirical relationships between the quantities generated from fake images.
  • define the fit region and window region based on the 1st radial moments
  • use the kron S/N to determine if analysis is performed for extended sources, not the psf S/N
  • remove the old 'basic deblend' which did not really do any deblending and is superceeded by the deblending in KronIterate and the footprint analysis
Location:
trunk/psphot
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src

    • Property svn:ignore
      •  

        old new  
        2222psphotMakePSF
        2323psphotStack
         24psphotModelTest
  • trunk/psphot/src/psphotExtendedSourceAnalysis.c

    r31154 r32348  
    22
    33// measure the elliptical radial profile and use this to measure the petrosian parameters for the sources
    4 // XXX this function needs to be threaded
    54
    65// for now, let's store the detections on the readout->analysis for each readout
     
    87{
    98    bool status = true;
     9
     10    fprintf (stdout, "\n");
     11    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Extended Source Analysis (Petrosians) ---");
    1012
    1113    // select the appropriate recipe information
     
    5961    }
    6062
    61     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    62     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
    63     assert (maskVal);
     63    // determine the number of allowed threads
     64    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     65    if (!status) {
     66        nThreads = 0;
     67    }
    6468
    6569    // get the sky noise from the background analysis; if this is missing, get the user-supplied value
     
    7074    }
    7175
     76    // source analysis is done in S/N order (brightest first)
     77    sources = psArraySort (sources, pmSourceSortByFlux);
     78
     79    // option to limit analysis to a specific region
     80    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
     81    psRegion *AnalysisRegion = psRegionAlloc(0,0,0,0);
     82    *AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
     83    if (psRegionIsNaN (*AnalysisRegion)) psAbort("analysis region mis-defined");
     84
     85    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
     86    int Cx = 1, Cy = 1;
     87    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     88
     89    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
     90
     91    for (int i = 0; i < cellGroups->n; i++) {
     92
     93        psArray *cells = cellGroups->data[i];
     94
     95        for (int j = 0; j < cells->n; j++) {
     96
     97            // allocate a job -- if threads are not defined, this just runs the job
     98            psThreadJob *job = psThreadJobAlloc ("PSPHOT_EXTENDED_ANALYSIS");
     99
     100            psArrayAdd(job->args, 1, readout);
     101            psArrayAdd(job->args, 1, cells->data[j]); // sources
     102            psArrayAdd(job->args, 1, AnalysisRegion);
     103            psArrayAdd(job->args, 1, recipe);
     104
     105            PS_ARRAY_ADD_SCALAR(job->args, skynoise, PS_TYPE_F32);
     106
     107            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
     108            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npetro
     109            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nannuli
     110
     111// set this to 0 to run without threading
     112# if (1)           
     113            if (!psThreadJobAddPending(job)) {
     114                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     115                psFree(AnalysisRegion);
     116                return false;
     117            }
     118# else
     119            if (!psphotExtendedSourceAnalysis_Threaded(job)) {
     120                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     121                psFree(AnalysisRegion);
     122                return false;
     123            }
     124            psScalar *scalar = NULL;
     125            scalar = job->args->data[5];
     126            Next += scalar->data.S32;
     127            scalar = job->args->data[6];
     128            Npetro += scalar->data.S32;
     129            scalar = job->args->data[7];
     130            Nannuli += scalar->data.S32;
     131            psFree(job);
     132# endif
     133        }
     134
     135        // wait for the threads to finish and manage results
     136        if (!psThreadPoolWait (false)) {
     137            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     138            psFree(AnalysisRegion);
     139            return false;
     140        }
     141
     142        // we have only supplied one type of job, so we can assume the types here
     143        psThreadJob *job = NULL;
     144        while ((job = psThreadJobGetDone()) != NULL) {
     145            if (job->args->n < 1) {
     146                fprintf (stderr, "error with job\n");
     147            } else {
     148                psScalar *scalar = NULL;
     149                scalar = job->args->data[5];
     150                Next += scalar->data.S32;
     151                scalar = job->args->data[6];
     152                Npetro += scalar->data.S32;
     153                scalar = job->args->data[7];
     154                Nannuli += scalar->data.S32;
     155            }
     156            psFree(job);
     157        }
     158    }
     159    psFree (cellGroups);
     160    psFree(AnalysisRegion);
     161
     162    psLogMsg ("psphot", PS_LOG_WARN, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
     163    psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
     164    psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
     165
     166    psphotVisualShowResidualImage (readout, false);
     167
     168    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     169    if (doPetrosian) {
     170        psphotVisualShowPetrosians (sources);
     171    }
     172
     173    return true;
     174}
     175
     176bool psphotExtendedSourceAnalysis_Threaded (psThreadJob *job) {
     177
     178    bool status;
     179
     180    int Next = 0;
     181    int Npetro = 0;
     182    int Nannuli = 0;
     183
     184    // arguments: readout, sources, models, region, psfSize, maskVal, markVal
     185    pmReadout *readout      = job->args->data[0];
     186    psArray *sources        = job->args->data[1];
     187    psRegion *region        = job->args->data[2];
     188    psMetadata *recipe      = job->args->data[3];
     189
     190    float skynoise          = PS_SCALAR_VALUE(job->args->data[4],F32);
     191
    72192    // S/N limit to perform full non-linear fits
    73193    float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
     
    78198    bool doPetroStars   = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS");
    79199
    80     // source analysis is done in S/N order (brightest first)
    81     sources = psArraySort (sources, pmSourceSortByFlux);
    82 
    83     // option to limit analysis to a specific region
    84     char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
    85     psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
    86     if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
     200    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     201    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     202    assert (maskVal);
    87203
    88204    // choose the sources of interest
     
    90206
    91207        pmSource *source = sources->data[i];
     208
     209        // if we have checked the source validity on the basis of the object set, then
     210        // we either skip these tests below or we skip the source completely
     211        if (source->tmpFlags & PM_SOURCE_TMPF_STACK_SKIP) continue;
     212        if (source->tmpFlags & PM_SOURCE_TMPF_STACK_KEEP) goto keepSource;
    92213
    93214        // skip PSF-like and non-astronomical objects
     
    104225
    105226        // limit selection to some SN limit
    106         assert (source->peak); // how can a source not have a peak?
    107         if (sqrt(source->peak->detValue) < SN_LIM) continue;
    108 
    109         // limit selection by analysis region
    110         if (source->peak->x < AnalysisRegion.x0) continue;
    111         if (source->peak->y < AnalysisRegion.y0) continue;
    112         if (source->peak->x > AnalysisRegion.x1) continue;
    113         if (source->peak->y > AnalysisRegion.y1) continue;
     227        // assert (source->peak); // how can a source not have a peak?
     228        // limit selection to some SN limit
     229        bool skipSource = false;
     230        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     231            skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr);
     232        } else {
     233            skipSource = (sqrt(source->peak->detValue) < SN_LIM);
     234        }
     235        if (skipSource) continue;
     236
     237        // limit selection by analysis region (this automatically apply
     238        if (source->peak->x < region->x0) continue;
     239        if (source->peak->y < region->y0) continue;
     240        if (source->peak->x > region->x1) continue;
     241        if (source->peak->y > region->y1) continue;
     242
     243    keepSource:
    114244
    115245        // replace object in image
     
    159289    }
    160290
    161     psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
    162     psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
    163     psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
    164 
    165     psphotVisualShowResidualImage (readout, false);
    166 
    167     if (doPetrosian) {
    168         psphotVisualShowPetrosians (sources);
    169     }
    170 
    171     // fprintf (stderr, "xsrc : tried %ld objects\n", sources->n);
     291    psScalar *scalar = NULL;
     292
     293    // change the value of a scalar on the array (wrap this and put it in psArray.h)
     294    scalar = job->args->data[5];
     295    scalar->data.S32 = Next;
     296
     297    scalar = job->args->data[6];
     298    scalar->data.S32 = Npetro;
     299
     300    scalar = job->args->data[7];
     301    scalar->data.S32 = Nannuli;
    172302
    173303    return true;
Note: See TracChangeset for help on using the changeset viewer.