IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 16, 2012, 4:21:50 PM (14 years ago)
Author:
bills
Message:

Do Kron measurements on smoothed image. Version with instrumentation.

File:
1 edited

Legend:

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

    r33837 r33877  
    11# include "psphotInternal.h"
    22
     3#define NO_USE_SE_KR   1
     4#define NO_SAVE_IMAGES 1
     5
    36bool psphotKronWindowSetSource(pmSource *source, psImage *kronWindow, bool useKronRadius, bool insert, bool oldWindow);
    4 bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal, bool applyWeight, bool smooth);
     7bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal, bool applyWeight, psImage *smoothedPixels);
     8
    59
    610bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule)
     
    4145        // psAssert (psf, "missing psf?");
    4246
    43         if (!psphotKronIterateReadout (config, recipe, view, readout, sources, psf)) {
     47        if (!psphotKronIterateReadout (config, recipe, view, filerule, readout, sources, psf, i)) {
    4448            psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for %s entry %d", filerule, i);
    4549            return false;
     
    5357bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max);
    5458
    55 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf) {
     59bool pass1 = true;
     60// This is defined in pmSource.c
     61extern psString psphot_outroot;
     62
     63#ifdef USE_SE_KR
     64static int   nKR = 0;
     65// input list indexed by list file's source->id
     66static float kr_sextractor[10000];
     67static int used[10000];
     68
     69int numMatched = 0;
     70
     71#define SE_KR_USED 0x800
     72
     73static void find_se_kr(pmSource *source) {
     74    int sid = source->id;
     75    if (isfinite(kr_sextractor[sid])) {
     76        source->moments->Mrf = kr_sextractor[sid] / 2.5;
     77        source->tmpFlags |= SE_KR_USED;
     78        numMatched++;
     79    }
     80}
     81
     82static void getxy(pmSource *source, float *pX, float *pY) {
     83    float x, y;
     84    if (source->modelPSF) {
     85        psF32 *PAR = source->modelPSF->params->data.F32;
     86        x = PAR[PM_PAR_XPOS];
     87        y = PAR[PM_PAR_YPOS];
     88    } else if (pmSourcePositionUseMoments(source)) {
     89        x = source->moments->Mx;
     90        y = source->moments->My;
     91    } else {
     92        x = source->peak->x;
     93        y = source->peak->y;
     94    }
     95    *pX = x;
     96    *pY = y;
     97}
     98
     99static void build_kr_list(psArray *sources) {
     100    // write list of source->id X Y to a file
     101    pid_t pid = getpid();
     102    char filename[40];
     103    sprintf(filename, "sources.%d.list", pid);
     104    FILE *out = fopen(filename, "w");
     105    for (int i=0; i < sources->n; i++) {
     106        pmSource *source = sources->data[i];
     107        float x, y;
     108        getxy(source, &x, &y);
     109        fprintf(out, "%6.3f %6.3f %5d\n", x, y, source->id);
     110    }
     111    fclose(out);
     112    // run gcompare on that file
     113
     114    char matchedfilename[20];
     115    sprintf(matchedfilename, "sources.%d.matched", pid);
     116    char command[80];
     117    sprintf(command, "rungcompare %s %s", filename, matchedfilename);
     118    int rc = system(command);
     119    if (rc) {
     120        fprintf(stderr, "failed to read matched list %d %d\n", rc, rc >> 8);
     121        return;
     122    }
     123
     124    unlink(filename);
     125
     126    for (int i = 0; i < 10000; i++) {
     127        used[i] = -1;
     128        kr_sextractor[i] = NAN;
     129    }
     130    int sid;
     131    int ipp_idet;
     132    float kr;
     133    // read the results to build the kr_sextractor
     134    FILE *in = fopen(matchedfilename, "r");
     135    while (fscanf(in, "%d %f %d", &sid, &kr, &ipp_idet) > 0) {
     136        // take first match for each sid ...
     137        if (!isfinite(kr_sextractor[sid])) {
     138            // .. and for each ipp_idet Since the lists are sorted in
     139            // order of SN this makes it more likely to get the right match
     140            if (used[ipp_idet] == -1) {
     141                kr_sextractor[sid] = kr;
     142                used[ipp_idet] = sid;
     143                nKR++;
     144            } else {
     145                fprintf(stderr, "match for %d %d is already used for %d\n",
     146                    sid, ipp_idet, used[ipp_idet]);
     147            }
     148        }
     149    }
     150    fclose(in);
     151    unlink(matchedfilename);
     152}
     153
     154#endif // USE_SE_KR
     155
     156bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index) {
    56157
    57158    bool status = false;
     
    64165    psTimerStart ("psphot.kron");
    65166
     167#ifdef USE_SE_KR
     168    if (!pass1) {
     169        build_kr_list(sources);
     170    }
     171#endif
     172
    66173    // determine the number of allowed threads
    67174    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     
    97204    if (!status) {
    98205        KRON_SMOOTH = false;
     206    }
     207    float KRON_SMOOTH_SIGMA = psMetadataLookupF32 (&status, recipe, "KRON_SMOOTH_SIGMA");
     208    if (!status) {
     209        KRON_SMOOTH_SIGMA = 1.7;
     210    }
     211    float KRON_SMOOTH_NSIGMA = psMetadataLookupS32 (&status, recipe, "KRON_SMOOTH_NSIGMA");
     212    if (!status) {
     213        KRON_SMOOTH_NSIGMA = 2;
    99214    }
    100215
     
    122237
    123238    // start with the currently known moments (Mxx, Myy, Mxy) and generate a window image
     239#ifdef USE_SE_KR
     240    int previous = numMatched;
     241#endif
    124242    for (int i = 0; i < sources->n; i++) {
    125243
     
    129247        // (this skips really bad sources (no peak, no moments, DEFECT)
    130248        psphotKronWindowSetSource (source, kronWindow, false, true, KRON_APPLY_WINDOW);
    131     }
     249#ifdef USE_SE_KR
     250        if (!pass1) {
     251            find_se_kr(source);
     252        }
     253#endif
     254    }
     255#ifdef USE_SE_KR
     256    if (!pass1) {
     257        fprintf(stdout, "Matched %d sources previous %d\n", numMatched, previous);
     258    }
     259#endif
     260
     261    // We measure the Kron Radius on a smoothed copy of the readout image
     262    psImage *smoothedImage = NULL;
     263    if (KRON_SMOOTH) {
     264        // Build the smoothed source image
     265        // Replace the subtracted sources
     266        psphotReplaceAllSourcesReadout(config, view, filerule, index, recipe, false);
     267        // Copy the image and smooth
     268        psTimerStart ("psphot.kron.smooth");
     269        smoothedImage = psImageCopy(NULL, readout->image, PS_TYPE_F32);
     270        psImageSmooth(smoothedImage, KRON_SMOOTH_SIGMA, KRON_SMOOTH_NSIGMA);
     271        psLogMsg ("psphot.kron", PS_LOG_WARN, "Smoothed image %f sec\n", psTimerMark ("psphot.kron.smooth"));
     272
     273        // remove the sources
     274        psphotRemoveAllSourcesReadout( config, view, filerule, index, recipe, false );
     275        // Now subtract smooth versions of the sources from the smoothed image
     276        psTimerStart ("psphot.kron.smooth.sources");
     277        for (int i=0; i< sources->n; i++) {
     278            pmSource *source = sources->data[i];
     279            // If source has been subtracted from the readout image subtract a "smoothed" version from the smoothedImage
     280            if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
     281                // cache copy of smoothedPixels in the source
     282                // tmpPtr is for use by a single "module" and must be null otherwise
     283                psAssert(source->tmpPtr == NULL, "source->tmpPtr is not null!");
     284
     285                psImage *smoothedPixels = psImageSubset(smoothedImage, source->region);
     286                source->tmpPtr = (psPtr) smoothedPixels;
     287                pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, false, maskVal, 0, 0);
     288            }
     289        }
     290        psLogMsg ("psphot.kron", PS_LOG_WARN, " removed %ld smoothed sources %f sec\n", sources->n, psTimerMark ("psphot.kron.smooth.sources"));
     291
     292    }
     293
     294#ifdef SAVE_IMAGES
     295    psphot_outroot = psMetadataLookupStr(&status, config->arguments, "OUTPUT");
     296    {
     297        // Save the background subtracted image
     298        psString fn = NULL;
     299        psStringAppend(&fn, "%s.p%d.src.sub.fits", psphot_outroot, pass1 ? 1 : 2);
     300        psphotSaveImage(0, readout->image, fn);
     301        psFree(fn);
     302        fn = NULL;
     303        if (KRON_SMOOTH) {
     304            psStringAppend(&fn, "%s.p%d.src.sub.sm.fits", psphot_outroot, pass1 ? 1 : 2);
     305            psphotSaveImage(0, smoothedImage, fn);
     306            psFree(fn);
     307        }
     308        if (KRON_APPLY_WINDOW) {
     309            psStringAppend(&fn, "%s.p%d.window.fits", psphot_outroot, pass1 ? 1 : 2);
     310            psphotSaveImage(0, kronWindow, fn);
     311            psFree(fn);
     312        }
     313    }
     314#endif
    132315
    133316    // threaded measurement of the source magnitudes
     
    157340            PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WEIGHT, PS_TYPE_S32);
    158341            PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_APPLY_WINDOW, PS_TYPE_S32);
    159             PS_ARRAY_ADD_SCALAR(job->args, (psS32) KRON_SMOOTH, PS_TYPE_S32);
     342            PS_ARRAY_ADD_SCALAR(job->args, KRON_SMOOTH_SIGMA,  PS_TYPE_F32);
     343            psArrayAdd(job->args, 1, smoothedImage);
    160344
    161345// set this to 0 to run without threading
    162 # if (0)
     346# if (1)
    163347            if (!psThreadJobAddPending(job)) {
    164348                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     
    192376    psFree (cellGroups);
    193377    psFree (kronWindow);
     378    psFree (smoothedImage);
     379    if (pass1) {
     380        pass1 = false;
     381    }
    194382
    195383    psLogMsg ("psphot.kron", PS_LOG_WARN, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n);
     
    209397    bool KRON_APPLY_WEIGHT          = PS_SCALAR_VALUE(job->args->data[8],S32);
    210398    bool KRON_APPLY_WINDOW          = PS_SCALAR_VALUE(job->args->data[9],S32);
    211     bool KRON_SMOOTH                = PS_SCALAR_VALUE(job->args->data[10],S32);
    212 
     399    float KRON_SMOOTH_SIGMA         = PS_SCALAR_VALUE(job->args->data[10],F32);
     400    psImage *smoothedImage          = job->args->data[11];
     401
     402    // psImage *smoothedPixels = NULL;
    213403    for (int j = 0; j < KRON_ITERATIONS; j++) {
    214404        for (int i = 0; i < sources->n; i++) {
     
    224414            // replace object in image
    225415            bool reSubtract = false;
     416            psImage *smoothedPixels = NULL;
    226417            if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
    227                 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     418                pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     419                smoothedPixels = (psImage *) source->tmpPtr;
     420                if (smoothedPixels) {
     421                    // psFree(source->tmpPtr);
     422                    // smoothedPixels = psImageSubset(smoothedImage, source->region);
     423                    pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, true, maskVal, 0, 0);
     424                    // source->tmpPtr = smoothedPixels;
     425                }
    228426                reSubtract = true;
    229427            }
     
    251449
    252450            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
    253             pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
     451            bool extend = pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2);
    254452            psAssert (source->pixels, "WTF?");
     453            if (extend && smoothedPixels) {
     454                psFree(source->tmpPtr);
     455                smoothedPixels = psImageSubset(smoothedImage, source->region);
     456                psAssert (smoothedPixels, "WTF?");
     457                source->tmpPtr = (psPtr) smoothedPixels ;
     458            }
     459
    255460
    256461            // clear the window function for this source based on the moments
     462            // Note this function also applies cuts on the source and returns false if it
     463            // does not meet the requirements for measuring the Kron Radius or Magnitude.
     464            // Not that it performs that function even if KRON_APPLY_WINDOW is false
    257465            if (psphotKronWindowSetSource (source, kronWindow, (j > 0), false, KRON_APPLY_WINDOW)) {
    258466
     467#ifdef SAVE_IMAGES
     468#ifdef SAVE_SOURCE_IMAGES
     469                if (j == 1 && !pass1) {
     470                    char fn[80];
     471                    if (smoothedPixels) {
     472                        sprintf(fn, "%s.s.%d.p%d.sm.fits", psphot_outroot, source->id, pass1 ? 1 : 2);
     473                        psphotSaveImage(0, smoothedPixels, fn);
     474                    }
     475                    sprintf(fn, "%s.s.%d.p%d.fits", psphot_outroot, source->id, pass1 ? 1 : 2);
     476                    psphotSaveImage(0, source->pixels, fn);
     477                }
     478#endif
     479#endif
     480
    259481                // this function populates moments->Mrf,KronFlux,KronFluxErr
    260                 psphotKronWindowMag (source, kronWindow, windowRadius, MIN_KRON_RADIUS, maskVal, KRON_APPLY_WEIGHT, KRON_SMOOTH);
     482                psphotKronWindowMag (source, kronWindow, windowRadius, MIN_KRON_RADIUS, maskVal, KRON_APPLY_WEIGHT, smoothedPixels);
    261483                psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    262484
     
    267489            // if we subtracted it above, re-subtract the object, leave local sky
    268490            if (reSubtract) {
    269                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     491                pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     492                if (smoothedPixels) {
     493                    pmSourceSmoothOp(source, PM_MODEL_OP_FUNC, smoothedPixels, KRON_SMOOTH_SIGMA, false, maskVal, 0, 0);
     494                    if (j + 1 == KRON_ITERATIONS) {
     495                        // We're done with the smoothedPixels
     496                        psFree(source->tmpPtr);
     497                        source->tmpPtr = NULL;
     498                        smoothedPixels = NULL;
     499                    }
     500                }
    270501            }
    271502        }
    272503    }
     504    // psFree(smoothedPixels);
    273505    return true;
    274506}
    275507
    276508bool psphotKronWindowMag (pmSource *source, psImage *kronWindow, float radius, float minKronRadius, psImageMaskType maskVal,
    277 bool applyWeight, bool smooth) {
     509    bool applyWeight, psImage *smoothedPixels) {
    278510
    279511    PS_ASSERT_PTR_NON_NULL(source, false);
     
    296528    // Xn  = SUM (x - xc)^n * (z - sky)
    297529
     530
    298531    psF32 RF = 0.0;
    299532    psF32 RS = 0.0;
     
    315548
    316549    psF32 **vPix;
    317     psImage *smoothedImage = NULL;;
    318     if (smooth) {
    319         smoothedImage = psImageCopy(NULL, source->pixels, PS_TYPE_F32);
    320         psImageSmooth(smoothedImage, 1.7, 2);
    321         vPix = smoothedImage->data.F32;
     550    if (smoothedPixels) {
     551        vPix = smoothedPixels->data.F32;
    322552    } else {
    323553        vPix = source->pixels->data.F32;
     
    376606            psF32 rs = 0.5 * (fDiff1 + fDiff2);
    377607
     608#ifdef BE_SIMPLE_MINDED
     609            rf = vPix[row][col] * sqrt(r2);
     610            rs = vPix[row][col];
     611#endif
     612
    378613            RF  += rf;
    379614            RS  += rs;
     
    386621        Mrf = MIN (radius, Mrf);
    387622    }
     623#ifdef USE_SE_KR
     624    if (source->tmpFlags & SE_KR_USED) {
     625        // we are using the sextratcor KR for this source set it back
     626        Mrf = source->moments->Mrf;
     627    }
     628#endif
    388629
    389630    // Calculate the Kron magnitude (make this block optional?)
     
    399640    // smoothed image above)
    400641    vPix = source->pixels->data.F32;
     642
    401643
    402644    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     
    433675    source->moments->KronFlux    = Sum;
    434676    source->moments->KronFluxErr = sqrt(Var);
    435     if (smoothedImage) {
    436         psFree(smoothedImage);
    437     }
    438677
    439678    return true;
     
    451690    psAssert(kronWindow, "need a window");
    452691
    453     if (source->moments->Mrf < 0) return false;
     692    if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
    454693
    455694    if (!applyWindow) {
     
    478717    }
    479718
    480     float scale = fabs(0.5 * source->moments->Mrf / axes.major);
     719    // Why this factor of 0.5 ?
     720    float scale = 0.5 * source->moments->Mrf / axes.major;
    481721    axes.major *= scale;
    482722    axes.minor *= scale;
     
    489729    }
    490730
    491     float Sxx = PS_SQR(shape.sx);
    492     float Syy = PS_SQR(shape.sy);
    493     float Sxy = -1. * shape.sxy;
    494731    float Smajor = axes.major;
    495732
     
    499736    int maxY = PS_MIN(PS_MAX(Yo + 5*Smajor, 0), Ny - 1);
    500737
    501     float rMxx = 0.5 / Sxx;
    502     float rMyy = 0.5 / Syy;
     738    float rMxx = 0.5 / PS_SQR(shape.sx);
     739    float rMyy = 0.5 / PS_SQR(shape.sy);
     740    float Sxy = -1. * shape.sxy;    // factor of -1 is included to match the previous window function
     741                                    // implementation. XXX: Is this correct?
    503742
    504743    for (int iy = minY; iy < maxY; iy++) {
Note: See TracChangeset for help on using the changeset viewer.