IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 26, 2010, 9:18:39 AM (16 years ago)
Author:
Serge CHASTEL
Message:

Merging trunk in branch

Location:
branches/sc_branches/trunkTest
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/sc_branches/trunkTest

  • branches/sc_branches/trunkTest/psphot

    • Property svn:mergeinfo deleted
  • branches/sc_branches/trunkTest/psphot/src/psphotVisual.c

    r28128 r29060  
    6666    int myKapa = psphotKapaChannel (channel);
    6767    if (!(strcasecmp (overlay, "all"))) {
    68       KiiEraseOverlay (myKapa, "red");
    69       KiiEraseOverlay (myKapa, "green");
    70       KiiEraseOverlay (myKapa, "blue");
    71       KiiEraseOverlay (myKapa, "yellow");
    72       return true;
     68        KiiEraseOverlay (myKapa, "red");
     69        KiiEraseOverlay (myKapa, "green");
     70        KiiEraseOverlay (myKapa, "blue");
     71        KiiEraseOverlay (myKapa, "yellow");
     72        return true;
    7373    }
    7474    KiiEraseOverlay (myKapa, overlay);
     
    182182bool psphotVisualShowImage (pmReadout *readout) {
    183183
    184     if (!pmVisualIsVisual()) return true;
     184    if (!pmVisualTestLevel("psphot.image", 1)) return true;
    185185
    186186    int kapa = psphotKapaChannel (1);
     
    199199    pmReadout *backgnd;
    200200
    201     if (!DEBUG && !pmVisualIsVisual()) return true;
     201    if (!pmVisualTestLevel("psphot.image.backgnd", 2)) return true;
    202202
    203203    int kapa = psphotKapaChannel (1);
     
    208208
    209209    if (file->mode == PM_FPA_MODE_INTERNAL) {
    210         backgnd = file->readout;
     210        backgnd = file->readout;
    211211    } else {
    212         backgnd = pmFPAviewThisReadout (view, file->fpa);
     212        backgnd = pmFPAviewThisReadout (view, file->fpa);
    213213    }
    214214
     
    222222bool psphotVisualShowSignificance (psImage *image, float min, float max) {
    223223
    224     if (!DEBUG && !pmVisualIsVisual()) return true;
     224    if (!pmVisualTestLevel("psphot.image.signif", 2)) return true;
    225225
    226226    int kapa = psphotKapaChannel (1);
     
    233233}
    234234
     235bool psphotVisualShowLogSignificance (psImage *image, float min, float max) {
     236
     237    if (!pmVisualTestLevel("psphot.image.logsignif", 3)) return true;
     238
     239    int kapa = psphotKapaChannel (1);
     240    if (kapa == -1) return false;
     241
     242    psImage *lsig = (psImage *) psUnaryOp (NULL, image, "log");
     243    psphotVisualRangeImage (kapa, lsig, "log-signif", 2, min, max);
     244    psFree (lsig);
     245
     246    pmVisualAskUser(NULL);
     247    return true;
     248}
     249
     250// XXX : requires psphotVisualShowImage
    235251bool psphotVisualShowPeaks (pmDetections *detections) {
    236252
     
    238254    KiiOverlay *overlay;
    239255
    240     if (!DEBUG && !pmVisualIsVisual()) return true;
     256    if (!pmVisualTestLevel("psphot.objects.peaks", 1)) return true;
    241257
    242258    int kapa = psphotKapaChannel (1);
     
    252268    for (int i = 0; i < peaks->n; i++) {
    253269
    254         pmPeak *peak = peaks->data[i];
    255         if (peak == NULL) continue;
    256 
    257         overlay[Noverlay].type = KII_OVERLAY_BOX;
    258         overlay[Noverlay].x = peak->xf;
    259         overlay[Noverlay].y = peak->yf;
    260         overlay[Noverlay].dx = 2.0;
    261         overlay[Noverlay].dy = 2.0;
    262         overlay[Noverlay].angle = 0.0;
    263         overlay[Noverlay].text = NULL;
    264         Noverlay ++;
     270        pmPeak *peak = peaks->data[i];
     271        if (peak == NULL) continue;
     272
     273        overlay[Noverlay].type = KII_OVERLAY_BOX;
     274        overlay[Noverlay].x = peak->xf;
     275        overlay[Noverlay].y = peak->yf;
     276        overlay[Noverlay].dx = 2.0;
     277        overlay[Noverlay].dy = 2.0;
     278        overlay[Noverlay].angle = 0.0;
     279        overlay[Noverlay].text = NULL;
     280        Noverlay ++;
    265281    }
    266282
     
    272288}
    273289
     290// XXX : requires psphotVisualShowImage
    274291bool psphotVisualShowFootprints (pmDetections *detections) {
    275292
     
    277294    KiiOverlay *overlay;
    278295
    279     if (!DEBUG && !pmVisualIsVisual()) return true;
     296    if (!pmVisualTestLevel("psphot.objects.footprints", 3)) return true;
    280297
    281298    int kapa = psphotKapaChannel (1);
     
    292309    for (int i = 0; i < footprints->n; i++) {
    293310
    294         pmSpan *span = NULL;
    295 
    296         pmFootprint *footprint = footprints->data[i];
    297         if (footprint == NULL) continue;
    298         if (footprint->spans == NULL) continue;
    299         if (footprint->spans->n < 1) continue;
    300 
    301         // draw the top
    302         // XXX need to allow top (and bottom) to have more than one span
    303         span = footprint->spans->data[0];
    304         overlay[Noverlay].type = KII_OVERLAY_LINE;
    305         overlay[Noverlay].x = span->x0;
    306         overlay[Noverlay].y = span->y;
    307         overlay[Noverlay].dx = span->x1 - span->x0;
    308         overlay[Noverlay].dy = 0;
    309         overlay[Noverlay].angle = 0.0;
    310         overlay[Noverlay].text = NULL;
    311         Noverlay ++;
    312         CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    313 
    314         int ys = span->y;
    315         int x0s = span->x0;
    316         int x1s = span->x1;
    317 
    318         // draw the outer span edges
    319         for (int j = 1; j < footprint->spans->n; j++) {
    320             pmSpan *span1 = footprint->spans->data[j];
    321 
    322             int ye = span1->y;
    323             int x0e = span1->x0;
    324             int x1e = span1->x1;
    325 
    326             // we cannot have two discontinuous spans on the top or bottom, right? (no, probably not right)
    327             // find all of the spans in this row and generate x0e, x01:
    328             for (int k = j + 1; k < footprint->spans->n; k++) {
    329                 pmSpan *span2 = footprint->spans->data[k];
    330                 if (span2->y > span1->y) break;
    331                 x0e = PS_MIN (x0e, span2->x0);
    332                 x1e = PS_MAX (x1e, span2->x1);
    333                 j++;
    334             }
    335 
    336             overlay[Noverlay].type = KII_OVERLAY_LINE;
    337             overlay[Noverlay].x = x0s;
    338             overlay[Noverlay].y = ys;
    339             overlay[Noverlay].dx = x0e - x0s;
    340             overlay[Noverlay].dy = ye - ys;
    341             overlay[Noverlay].angle = 0.0;
    342             overlay[Noverlay].text = NULL;
    343             Noverlay ++;
    344             CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    345 
    346             overlay[Noverlay].type = KII_OVERLAY_LINE;
    347             overlay[Noverlay].x = x1s;
    348             overlay[Noverlay].y = ys;
    349             overlay[Noverlay].dx = x1e - x1s;
    350             overlay[Noverlay].dy = ye - ys;
    351             overlay[Noverlay].angle = 0.0;
    352             overlay[Noverlay].text = NULL;
    353             Noverlay ++;
    354             CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    355 
    356             ys = ye;
    357             x0s = x0e;
    358             x1s = x1e;
    359         }
    360 
    361         // draw the bottom
    362         span = footprint->spans->data[footprint->spans->n - 1];
    363         overlay[Noverlay].type = KII_OVERLAY_LINE;
    364         overlay[Noverlay].x = span->x0;
    365         overlay[Noverlay].y = span->y;
    366         overlay[Noverlay].dx = span->x1 - span->x0;
    367         overlay[Noverlay].dy = 0;
    368         overlay[Noverlay].angle = 0.0;
    369         overlay[Noverlay].text = NULL;
    370         Noverlay ++;
    371         CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     311        pmSpan *span = NULL;
     312
     313        pmFootprint *footprint = footprints->data[i];
     314        if (footprint == NULL) continue;
     315        if (footprint->spans == NULL) continue;
     316        if (footprint->spans->n < 1) continue;
     317
     318        // draw the top
     319        // XXX need to allow top (and bottom) to have more than one span
     320        span = footprint->spans->data[0];
     321        overlay[Noverlay].type = KII_OVERLAY_LINE;
     322        overlay[Noverlay].x = span->x0;
     323        overlay[Noverlay].y = span->y;
     324        overlay[Noverlay].dx = span->x1 - span->x0;
     325        overlay[Noverlay].dy = 0;
     326        overlay[Noverlay].angle = 0.0;
     327        overlay[Noverlay].text = NULL;
     328        Noverlay ++;
     329        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     330
     331        int ys = span->y;
     332        int x0s = span->x0;
     333        int x1s = span->x1;
     334
     335        // draw the outer span edges
     336        for (int j = 1; j < footprint->spans->n; j++) {
     337            pmSpan *span1 = footprint->spans->data[j];
     338
     339            int ye = span1->y;
     340            int x0e = span1->x0;
     341            int x1e = span1->x1;
     342
     343            // we cannot have two discontinuous spans on the top or bottom, right? (no, probably not right)
     344            // find all of the spans in this row and generate x0e, x01:
     345            for (int k = j + 1; k < footprint->spans->n; k++) {
     346                pmSpan *span2 = footprint->spans->data[k];
     347                if (span2->y > span1->y) break;
     348                x0e = PS_MIN (x0e, span2->x0);
     349                x1e = PS_MAX (x1e, span2->x1);
     350                j++;
     351            }
     352
     353            overlay[Noverlay].type = KII_OVERLAY_LINE;
     354            overlay[Noverlay].x = x0s;
     355            overlay[Noverlay].y = ys;
     356            overlay[Noverlay].dx = x0e - x0s;
     357            overlay[Noverlay].dy = ye - ys;
     358            overlay[Noverlay].angle = 0.0;
     359            overlay[Noverlay].text = NULL;
     360            Noverlay ++;
     361            CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     362
     363            overlay[Noverlay].type = KII_OVERLAY_LINE;
     364            overlay[Noverlay].x = x1s;
     365            overlay[Noverlay].y = ys;
     366            overlay[Noverlay].dx = x1e - x1s;
     367            overlay[Noverlay].dy = ye - ys;
     368            overlay[Noverlay].angle = 0.0;
     369            overlay[Noverlay].text = NULL;
     370            Noverlay ++;
     371            CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     372
     373            ys = ye;
     374            x0s = x0e;
     375            x1s = x1e;
     376        }
     377
     378        // draw the bottom
     379        span = footprint->spans->data[footprint->spans->n - 1];
     380        overlay[Noverlay].type = KII_OVERLAY_LINE;
     381        overlay[Noverlay].x = span->x0;
     382        overlay[Noverlay].y = span->y;
     383        overlay[Noverlay].dx = span->x1 - span->x0;
     384        overlay[Noverlay].dy = 0;
     385        overlay[Noverlay].angle = 0.0;
     386        overlay[Noverlay].text = NULL;
     387        Noverlay ++;
     388        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    372389    }
    373390
     
    379396}
    380397
     398// XXX : requires psphotVisualShowImage
    381399bool psphotVisualShowMoments (psArray *sources) {
    382400
     
    387405    psEllipseAxes axes;
    388406
    389     if (!DEBUG && !pmVisualIsVisual()) return true;
     407    if (!pmVisualTestLevel("psphot.objects.moments", 2)) return true;
    390408
    391409    int kapa = psphotKapaChannel (1);
     
    401419    for (int i = 0; i < sources->n; i++) {
    402420
    403         pmSource *source = sources->data[i];
    404         if (source == NULL) continue;
    405 
    406         pmMoments *moments = source->moments;
    407         if (moments == NULL) continue;
    408 
    409         overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
    410         overlay[Noverlay].x = moments->Mx;
    411         overlay[Noverlay].y = moments->My;
    412 
    413         emoments.x2 = moments->Mxx;
    414         emoments.xy = moments->Mxy;
    415         emoments.y2 = moments->Myy;
    416 
    417         axes = psEllipseMomentsToAxes (emoments, 20.0);
    418 
    419         overlay[Noverlay].dx = 2.0*axes.major;
    420         overlay[Noverlay].dy = 2.0*axes.minor;
    421 
    422         overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
    423 
    424         overlay[Noverlay].text = NULL;
    425         Noverlay ++;
     421        pmSource *source = sources->data[i];
     422        if (source == NULL) continue;
     423
     424        pmMoments *moments = source->moments;
     425        if (moments == NULL) continue;
     426
     427        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
     428        overlay[Noverlay].x = moments->Mx;
     429        overlay[Noverlay].y = moments->My;
     430
     431        emoments.x2 = moments->Mxx;
     432        emoments.xy = moments->Mxy;
     433        emoments.y2 = moments->Myy;
     434
     435        axes = psEllipseMomentsToAxes (emoments, 20.0);
     436
     437        overlay[Noverlay].dx = 2.0*axes.major;
     438        overlay[Noverlay].dy = 2.0*axes.minor;
     439
     440        overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
     441
     442        overlay[Noverlay].text = NULL;
     443        Noverlay ++;
    426444    }
    427445
     
    439457    KapaSection section;
    440458
    441     if (!DEBUG && !pmVisualIsVisual()) return true;
     459    if (!pmVisualTestLevel("psphot.moments", 1)) return true;
    442460
    443461    int myKapa = psphotKapaChannel (2);
     
    456474    float Ymin = 1000.0, Ymax = 0.0;
    457475    {
    458         int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
    459         for (int n = 0; n < nRegions; n++) {
    460 
    461             char regionName[64];
    462             snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
    463             psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
    464 
    465             float psfX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
    466             float psfY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
    467             float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
    468             float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
    469 
    470             float X0 = psfX - 4.0*psfdX;
    471             float X1 = psfX + 4.0*psfdX;
    472             float Y0 = psfY - 4.0*psfdY;
    473             float Y1 = psfY + 4.0*psfdY;
    474 
    475             if (isfinite(X0)) { Xmin = PS_MIN(Xmin, X0); }
    476             if (isfinite(X1)) { Xmax = PS_MAX(Xmax, X1); }
    477             if (isfinite(Y0)) { Ymin = PS_MIN(Ymin, Y0); }
    478             if (isfinite(Y1)) { Ymax = PS_MAX(Ymax, Y1); }
    479         }
     476        int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
     477        for (int n = 0; n < nRegions; n++) {
     478
     479            char regionName[64];
     480            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
     481            psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
     482
     483            float psfX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
     484            float psfY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
     485            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
     486            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
     487
     488            float X0 = psfX - 4.0*psfdX;
     489            float X1 = psfX + 4.0*psfdX;
     490            float Y0 = psfY - 4.0*psfdY;
     491            float Y1 = psfY + 4.0*psfdY;
     492
     493            if (isfinite(X0)) { Xmin = PS_MIN(Xmin, X0); }
     494            if (isfinite(X1)) { Xmax = PS_MAX(Xmax, X1); }
     495            if (isfinite(Y0)) { Ymin = PS_MIN(Ymin, Y0); }
     496            if (isfinite(Y1)) { Ymax = PS_MAX(Ymax, Y1); }
     497        }
    480498    }
    481499    Xmin = PS_MAX(Xmin, -0.1);
     
    498516    int nF = 0;
    499517    for (int i = 0; i < sources->n; i++) {
    500         pmSource *source = sources->data[i];
    501         if (source->moments == NULL)
    502             continue;
    503 
    504         xFaint->data.F32[nF] = source->moments->Mxx;
    505         yFaint->data.F32[nF] = source->moments->Myy;
    506         mFaint->data.F32[nF] = -2.5*log10(source->moments->Sum);
    507         nF++;
    508 
    509         // XXX make this a user-defined cutoff
    510         if (source->moments->SN < SN_LIM)
    511             continue;
    512 
    513         xBright->data.F32[nB] = source->moments->Mxx;
    514         yBright->data.F32[nB] = source->moments->Myy;
    515         mBright->data.F32[nB] = -2.5*log10(source->moments->Sum);
    516         nB++;
     518        pmSource *source = sources->data[i];
     519        if (source->moments == NULL)
     520            continue;
     521
     522        xFaint->data.F32[nF] = source->moments->Mxx;
     523        yFaint->data.F32[nF] = source->moments->Myy;
     524        mFaint->data.F32[nF] = -2.5*log10(source->moments->Sum);
     525        nF++;
     526
     527        // XXX make this a user-defined cutoff
     528        if (source->moments->SN < SN_LIM)
     529            continue;
     530
     531        xBright->data.F32[nB] = source->moments->Mxx;
     532        yBright->data.F32[nB] = source->moments->Myy;
     533        mBright->data.F32[nB] = -2.5*log10(source->moments->Sum);
     534        nB++;
    517535    }
    518536    xFaint->n = nF;
     
    652670    // draw N circles to outline the clumps
    653671    {
    654         KapaSelectSection (myKapa, "MxxMyy");
    655 
    656         // draw a circle centered on psfX,Y with size of the psf limit
    657         psVector *xLimit  = psVectorAlloc (120, PS_TYPE_F32);
    658         psVector *yLimit  = psVectorAlloc (120, PS_TYPE_F32);
    659 
    660         int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
    661         float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA");
    662 
    663         graphdata.color = KapaColorByName ("blue");
    664         graphdata.style = 0;
    665 
    666         graphdata.xmin = Xmin;
    667         graphdata.ymin = Ymin;
    668         graphdata.xmax = Xmax;
    669         graphdata.ymax = Ymax;
    670         KapaSetLimits (myKapa, &graphdata);
    671 
    672         for (int n = 0; n < nRegions; n++) {
    673 
    674             char regionName[64];
    675             snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
    676             psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
    677 
    678             float psfX  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
    679             float psfY  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
    680             float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
    681             float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
    682             float Rx = psfdX * PSF_CLUMP_NSIGMA;
    683             float Ry = psfdY * PSF_CLUMP_NSIGMA;
    684 
    685             for (int i = 0; i < xLimit->n; i++) {
    686                 xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX;
    687                 yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
    688             }
    689             KapaPrepPlot (myKapa, xLimit->n, &graphdata);
    690             KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
    691             KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
    692         }
    693         psFree (xLimit);
    694         psFree (yLimit);
     672        KapaSelectSection (myKapa, "MxxMyy");
     673
     674        // draw a circle centered on psfX,Y with size of the psf limit
     675        psVector *xLimit  = psVectorAlloc (120, PS_TYPE_F32);
     676        psVector *yLimit  = psVectorAlloc (120, PS_TYPE_F32);
     677
     678        int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
     679        float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA");
     680
     681        graphdata.color = KapaColorByName ("blue");
     682        graphdata.style = 0;
     683
     684        graphdata.xmin = Xmin;
     685        graphdata.ymin = Ymin;
     686        graphdata.xmax = Xmax;
     687        graphdata.ymax = Ymax;
     688        KapaSetLimits (myKapa, &graphdata);
     689
     690        for (int n = 0; n < nRegions; n++) {
     691
     692            char regionName[64];
     693            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
     694            psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
     695
     696            float psfX  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
     697            float psfY  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
     698            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
     699            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
     700            float Rx = psfdX * PSF_CLUMP_NSIGMA;
     701            float Ry = psfdY * PSF_CLUMP_NSIGMA;
     702
     703            for (int i = 0; i < xLimit->n; i++) {
     704                xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX;
     705                yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
     706            }
     707            KapaPrepPlot (myKapa, xLimit->n, &graphdata);
     708            KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
     709            KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
     710        }
     711        psFree (xLimit);
     712        psFree (yLimit);
    695713    }
    696714
     
    721739    for (int i = 0; i < sources->n; i++) {
    722740
    723         pmSource *source = sources->data[i];
    724         if (source == NULL) continue;
    725 
    726         if (source->type != type) continue;
    727         if (mode && !(source->mode & mode)) continue;
    728 
    729         pmMoments *moments = source->moments;
    730         if (moments == NULL) continue;
    731 
    732         overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
    733         overlay[Noverlay].x = moments->Mx;
    734         overlay[Noverlay].y = moments->My;
    735 
    736         emoments.x2 = moments->Mxx;
    737         emoments.y2 = moments->Myy;
    738         emoments.xy = moments->Mxy;
    739 
    740         axes = psEllipseMomentsToAxes (emoments, 20.0);
    741 
    742         overlay[Noverlay].dx = 2.0*axes.major;
    743         overlay[Noverlay].dy = 2.0*axes.minor;
    744         overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
    745         overlay[Noverlay].text = NULL;
    746         Noverlay ++;
     741        pmSource *source = sources->data[i];
     742        if (source == NULL) continue;
     743
     744        if (source->type != type) continue;
     745        if (mode && !(source->mode & mode)) continue;
     746
     747        pmMoments *moments = source->moments;
     748        if (moments == NULL) continue;
     749
     750        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
     751        overlay[Noverlay].x = moments->Mx;
     752        overlay[Noverlay].y = moments->My;
     753
     754        emoments.x2 = moments->Mxx;
     755        emoments.y2 = moments->Myy;
     756        emoments.xy = moments->Mxy;
     757
     758        axes = psEllipseMomentsToAxes (emoments, 20.0);
     759
     760        overlay[Noverlay].dx = 2.0*axes.major;
     761        overlay[Noverlay].dy = 2.0*axes.minor;
     762        overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
     763        overlay[Noverlay].text = NULL;
     764        Noverlay ++;
    747765    }
    748766
     
    753771}
    754772
     773// XXX : requires psphotVisualShowImage
    755774bool psphotVisualShowRoughClass (psArray *sources) {
    756775
    757     if (!DEBUG && !pmVisualIsVisual()) return true;
     776    if (!pmVisualTestLevel("psphot.objects.size", 3)) return true;
    758777
    759778    int myKapa = psphotKapaChannel (1);
     
    776795bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf) {
    777796
    778     if (!DEBUG && !pmVisualIsVisual()) return true;
     797    if (!pmVisualTestLevel("psphot.psf.model", 1)) return true;
    779798
    780799    int myKapa = psphotKapaChannel (3);
     
    797816    // generate a fake model at each of the 3x3 image grid positions
    798817    for (int x = -2; x <= +2; x ++) {
    799         for (int y = -2; y <= +2; y ++) {
    800             // use the center of the center pixel of the image
    801             float xc = (int)((0.5 + 0.225*x)*readout->image->numCols) + readout->image->col0 + 0.5;
    802             float yc = (int)((0.5 + 0.225*y)*readout->image->numRows) + readout->image->row0 + 0.5;
    803 
    804             // assign the x and y coords to the image center
    805             // create an object with center intensity of 1000
    806             modelRef->params->data.F32[PM_PAR_SKY] = 0;
    807             modelRef->params->data.F32[PM_PAR_I0] = 1000;
    808             modelRef->params->data.F32[PM_PAR_XPOS] = xc;
    809             modelRef->params->data.F32[PM_PAR_YPOS] = yc;
    810 
    811             // create modelPSF from this model
    812             pmModel *model = pmModelFromPSF (modelRef, psf);
    813             if (!model) continue;
    814 
    815             // place the reference object in the image center
    816             // no need to mask the source here
    817             // XXX should we measure this for the analytical model only or the full model?
    818             pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
    819             pmModelAddWithOffset (funMosaic, NULL, model, PM_MODEL_OP_FUNC | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
    820             pmModelAddWithOffset (resMosaic, NULL, model, PM_MODEL_OP_RES0 | PM_MODEL_OP_RES1 | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
    821             psFree (model);
    822         }
     818        for (int y = -2; y <= +2; y ++) {
     819            // use the center of the center pixel of the image
     820            float xc = (int)((0.5 + 0.225*x)*readout->image->numCols) + readout->image->col0 + 0.5;
     821            float yc = (int)((0.5 + 0.225*y)*readout->image->numRows) + readout->image->row0 + 0.5;
     822
     823            // assign the x and y coords to the image center
     824            // create an object with center intensity of 1000
     825            modelRef->params->data.F32[PM_PAR_SKY] = 0;
     826            modelRef->params->data.F32[PM_PAR_I0] = 1000;
     827            modelRef->params->data.F32[PM_PAR_XPOS] = xc;
     828            modelRef->params->data.F32[PM_PAR_YPOS] = yc;
     829
     830            // create modelPSF from this model
     831            pmModel *model = pmModelFromPSF (modelRef, psf);
     832            if (!model) continue;
     833
     834            // place the reference object in the image center
     835            // no need to mask the source here
     836            // XXX should we measure this for the analytical model only or the full model?
     837            pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
     838            pmModelAddWithOffset (funMosaic, NULL, model, PM_MODEL_OP_FUNC | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
     839            pmModelAddWithOffset (resMosaic, NULL, model, PM_MODEL_OP_RES0 | PM_MODEL_OP_RES1 | PM_MODEL_OP_CENTER, 0, x*DX, y*DY);
     840            psFree (model);
     841        }
    823842    }
    824843
     
    842861    bool status;
    843862
    844     if (!DEBUG && !pmVisualIsVisual()) return true;
     863    if (!pmVisualTestLevel("psphot.psf.stars", 2)) return true;
    845864
    846865    int myKapa = psphotKapaChannel (3);
     
    871890    for (int i = 0; i < sources->n; i++) {
    872891
    873         pmSource *source = sources->data[i];
    874 
    875         bool keep = false;
    876         keep |= (source->mode & PM_SOURCE_MODE_PSFSTAR);
    877         if (!keep) continue;
    878 
    879         // how does this subimage get placed into the output image?
    880         // DX = source->pixels->numCols
    881         // DY = source->pixels->numRows
    882 
    883         if (dX + DX > NX) {
    884             // too wide for the rest of this row
    885             if (dX == 0) {
    886                 // alone on this row
    887                 NY += DY;
    888                 dX = 0;
    889                 dY = 0;
    890             } else {
    891                 // start the next row
    892                 NY += dY;
    893                 dX = DX;
    894                 dY = DY;
    895             }
    896         } else {
    897             // extend this row
    898             dX += DX;
    899             dY = PS_MAX (dY, DY);
    900         }
     892        pmSource *source = sources->data[i];
     893
     894        bool keep = false;
     895        keep |= (source->mode & PM_SOURCE_MODE_PSFSTAR);
     896        if (!keep) continue;
     897
     898        // how does this subimage get placed into the output image?
     899        // DX = source->pixels->numCols
     900        // DY = source->pixels->numRows
     901
     902        if (dX + DX > NX) {
     903            // too wide for the rest of this row
     904            if (dX == 0) {
     905                // alone on this row
     906                NY += DY;
     907                dX = 0;
     908                dY = 0;
     909            } else {
     910                // start the next row
     911                NY += dY;
     912                dX = DX;
     913                dY = DY;
     914            }
     915        } else {
     916            // extend this row
     917            dX += DX;
     918            dY = PS_MAX (dY, DY);
     919        }
    901920    }
    902921    NY += DY;
     
    918937    for (int i = 0; i < sources->n; i++) {
    919938
    920         pmSource *source = sources->data[i];
    921 
    922         bool keep = false;
    923         if (source->mode & PM_SOURCE_MODE_PSFSTAR) {
    924             nPSF ++;
    925             keep = true;
    926         }
    927         if (!keep) continue;
    928 
    929         if (Xo + DX > NX) {
    930             // too wide for the rest of this row
    931             if (Xo == 0) {
    932                 // place source alone on this row
    933                 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    934                 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    935                 psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
    936 
    937                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    938                 psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
    939 
    940                 if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    941 
    942                 Yo += DY;
    943                 Xo = 0;
    944                 dY = 0;
    945             } else {
    946                 // start the next row
    947                 Yo += dY;
    948                 Xo = 0;
    949 
    950                 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    951                 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    952                 psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
    953 
    954                 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    955                 psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
    956 
    957                 if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    958 
    959                 Xo = DX;
    960                 dY = DY;
    961             }
    962         } else {
    963             // extend this row
    964             bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    965             if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    966             psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
    967 
    968             pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    969             psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
    970             if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    971 
    972             Xo += DX;
    973             dY = PS_MAX (dY, DY);
    974         }
     939        pmSource *source = sources->data[i];
     940
     941        bool keep = false;
     942        if (source->mode & PM_SOURCE_MODE_PSFSTAR) {
     943            nPSF ++;
     944            keep = true;
     945        }
     946        if (!keep) continue;
     947
     948        if (Xo + DX > NX) {
     949            // too wide for the rest of this row
     950            if (Xo == 0) {
     951                // place source alone on this row
     952                bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     953                if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     954                psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
     955
     956                pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     957                psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
     958
     959                if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     960
     961                Yo += DY;
     962                Xo = 0;
     963                dY = 0;
     964            } else {
     965                // start the next row
     966                Yo += dY;
     967                Xo = 0;
     968
     969                bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     970                if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     971                psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
     972
     973                pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     974                psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
     975
     976                if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     977
     978                Xo = DX;
     979                dY = DY;
     980            }
     981        } else {
     982            // extend this row
     983            bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     984            if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     985            psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true);
     986
     987            pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     988            psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true);
     989            if (!subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     990
     991            Xo += DX;
     992            dY = PS_MAX (dY, DY);
     993        }
    975994    }
    976995
     
    9941013    bool status;
    9951014
    996     if (!DEBUG && !pmVisualIsVisual()) return true;
     1015    if (!pmVisualTestLevel("psphot.psf.sat", 3)) return true;
    9971016
    9981017    int myKapa = psphotKapaChannel (3);
     
    10231042    for (int i = 0; i < sources->n; i++) {
    10241043
    1025         pmSource *source = sources->data[i];
    1026 
    1027         // only show "real" saturated stars (not defects)
    1028         if (!(source->mode & PM_SOURCE_MODE_SATSTAR)) continue;;
    1029         if (source->mode & PM_SOURCE_MODE_DEFECT) continue;;
    1030 
    1031         // how does this subimage get placed into the output image?
    1032         // DX = source->pixels->numCols
    1033         // DY = source->pixels->numRows
    1034 
    1035         if (dX + DX > NX) {
    1036             // too wide for the rest of this row
    1037             if (dX == 0) {
    1038                 // alone on this row
    1039                 NY += DY;
    1040                 dX = 0;
    1041                 dY = 0;
    1042             } else {
    1043                 // start the next row
    1044                 NY += dY;
    1045                 dX = DX;
    1046                 dY = DY;
    1047             }
    1048         } else {
    1049             // extend this row
    1050             dX += DX;
    1051             dY = PS_MAX (dY, DY);
    1052         }
     1044        pmSource *source = sources->data[i];
     1045
     1046        // only show "real" saturated stars (not defects)
     1047        if (!(source->mode & PM_SOURCE_MODE_SATSTAR)) continue;;
     1048        if (source->mode & PM_SOURCE_MODE_DEFECT) continue;;
     1049
     1050        // how does this subimage get placed into the output image?
     1051        // DX = source->pixels->numCols
     1052        // DY = source->pixels->numRows
     1053
     1054        if (dX + DX > NX) {
     1055            // too wide for the rest of this row
     1056            if (dX == 0) {
     1057                // alone on this row
     1058                NY += DY;
     1059                dX = 0;
     1060                dY = 0;
     1061            } else {
     1062                // start the next row
     1063                NY += dY;
     1064                dX = DX;
     1065                dY = DY;
     1066            }
     1067        } else {
     1068            // extend this row
     1069            dX += DX;
     1070            dY = PS_MAX (dY, DY);
     1071        }
    10531072    }
    10541073    NY += DY;
     
    10681087    for (int i = 0; i < sources->n; i++) {
    10691088
    1070         pmSource *source = sources->data[i];
    1071 
    1072         // only show "real" saturated stars (not defects)
    1073         if (!(source->mode & PM_SOURCE_MODE_SATSTAR)) continue;;
    1074         if (source->mode & PM_SOURCE_MODE_DEFECT) continue;;
    1075         nSAT ++;
    1076 
    1077         if (Xo + DX > NX) {
    1078             // too wide for the rest of this row
    1079             if (Xo == 0) {
    1080                 // place source alone on this row
    1081                 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    1082                 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    1083                 psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
    1084                 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    1085 
    1086                 Yo += DY;
    1087                 Xo = 0;
    1088                 dY = 0;
    1089             } else {
    1090                 // start the next row
    1091                 Yo += dY;
    1092                 Xo = 0;
    1093 
    1094                 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    1095                 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    1096                 psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
    1097                 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    1098 
    1099                 Xo = DX;
    1100                 dY = DY;
    1101             }
    1102         } else {
    1103             // extend this row
    1104             bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
    1105             if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
    1106             psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
    1107             if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
    1108 
    1109             Xo += DX;
    1110             dY = PS_MAX (dY, DY);
    1111         }
     1089        pmSource *source = sources->data[i];
     1090
     1091        // only show "real" saturated stars (not defects)
     1092        if (!(source->mode & PM_SOURCE_MODE_SATSTAR)) continue;;
     1093        if (source->mode & PM_SOURCE_MODE_DEFECT) continue;;
     1094        nSAT ++;
     1095
     1096        if (Xo + DX > NX) {
     1097            // too wide for the rest of this row
     1098            if (Xo == 0) {
     1099                // place source alone on this row
     1100                bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     1101                if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     1102                psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
     1103                if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     1104
     1105                Yo += DY;
     1106                Xo = 0;
     1107                dY = 0;
     1108            } else {
     1109                // start the next row
     1110                Yo += dY;
     1111                Xo = 0;
     1112
     1113                bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     1114                if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     1115                psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
     1116                if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     1117
     1118                Xo = DX;
     1119                dY = DY;
     1120            }
     1121        } else {
     1122            // extend this row
     1123            bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     1124            if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
     1125            psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false);
     1126            if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
     1127
     1128            Xo += DX;
     1129            dY = PS_MAX (dY, DY);
     1130        }
    11121131    }
    11131132
     
    11511170    float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS] - source->pixels->row0;
    11521171    for (int iy = 0; iy < source->pixels->numRows; iy++) {
    1153         for (int ix = 0; ix < source->pixels->numCols; ix++) {
    1154             if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
    1155                 rb->data.F32[nb] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ;
    1156                 // rb->data.F32[nb] = hypot (ix - Xo, iy - Yo) ;
    1157                 Rb->data.F32[nb] = log10(rb->data.F32[nb]);
    1158                 fb->data.F32[nb] = log10(source->pixels->data.F32[iy][ix]);
    1159                 nb++;
    1160             } else {
    1161                 rg->data.F32[ng] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ;
    1162                 // rg->data.F32[ng] = hypot (ix - Xo, iy - Yo) ;
    1163                 Rg->data.F32[ng] = log10(rg->data.F32[ng]);
    1164                 fg->data.F32[ng] = log10(source->pixels->data.F32[iy][ix]);
    1165                 ng++;
    1166             }
    1167         }
     1172        for (int ix = 0; ix < source->pixels->numCols; ix++) {
     1173            if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {
     1174                rb->data.F32[nb] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ;
     1175                // rb->data.F32[nb] = hypot (ix - Xo, iy - Yo) ;
     1176                Rb->data.F32[nb] = log10(rb->data.F32[nb]);
     1177                fb->data.F32[nb] = log10(source->pixels->data.F32[iy][ix]);
     1178                nb++;
     1179            } else {
     1180                rg->data.F32[ng] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ;
     1181                // rg->data.F32[ng] = hypot (ix - Xo, iy - Yo) ;
     1182                Rg->data.F32[ng] = log10(rg->data.F32[ng]);
     1183                fg->data.F32[ng] = log10(source->pixels->data.F32[iy][ix]);
     1184                ng++;
     1185            }
     1186        }
    11681187    }
    11691188
     
    13581377    KapaSection section;  // put the positive profile in one and the residuals in another?
    13591378
    1360     if (!DEBUG && !pmVisualIsVisual()) return true;
     1379    if (!pmVisualTestLevel("psphot.profiles", 3)) return true;
    13611380
    13621381    int myKapa = psphotKapaChannel (2);
     
    13941413    for (int i = 0; i < sources->n; i++) {
    13951414
    1396         pmSource *source = sources->data[i];
    1397         if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
    1398 
    1399         psphotVisualPlotRadialProfile (myKapa, source, maskVal);
    1400 
    1401         // pause and wait for user input:
    1402         // continue, save (provide name), ??
    1403         char key[10];
    1404         fprintf (stdout, "[e]rase and continue? [o]verplot and continue? [s]kip rest of stars? : ");
    1405         if (!fgets(key, 8, stdin)) {
    1406             psWarning("Unable to read option");
    1407         }
    1408         if (key[0] == 'e') {
    1409             KapaClearPlots (myKapa);
    1410         }
    1411         if (key[0] == 's') {
    1412             break;
    1413         }
     1415        pmSource *source = sources->data[i];
     1416        if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
     1417
     1418        psphotVisualPlotRadialProfile (myKapa, source, maskVal);
     1419
     1420        // pause and wait for user input:
     1421        // continue, save (provide name), ??
     1422        char key[10];
     1423        fprintf (stdout, "[e]rase and continue? [o]verplot and continue? [s]kip rest of stars? : ");
     1424        if (!fgets(key, 8, stdin)) {
     1425            psWarning("Unable to read option");
     1426        }
     1427        if (key[0] == 'e') {
     1428            KapaClearPlots (myKapa);
     1429        }
     1430        if (key[0] == 's') {
     1431            break;
     1432        }
    14141433    }
    14151434
     
    14291448    return true;
    14301449
    1431     if (!DEBUG && !pmVisualIsVisual()) return true;
     1450    if (!pmVisualTestLevel("psphot.objects.flags", 3)) return true;
    14321451
    14331452    int myKapa = psphotKapaChannel (1);
     
    14451464    for (int i = 0; i < sources->n; i++) {
    14461465
    1447         float Xo, Yo, Rmaj, Rmin, cs, sn;
    1448 
    1449         pmSource *source = sources->data[i];
    1450         if (source == NULL) continue;
    1451 
    1452         pmMoments *moments = source->moments;
    1453         if (0) {
    1454             emoments.x2 = moments->Mxx;
    1455             emoments.y2 = moments->Myy;
    1456             emoments.xy = moments->Mxy;
    1457             Xo = moments->Mx;
    1458             Yo = moments->My;
    1459 
    1460             axes = psEllipseMomentsToAxes (emoments, 20.0);
    1461             Rmaj = 2.0*axes.major;
    1462             Rmin = 2.0*axes.minor;
    1463             cs = cos(axes.theta);
    1464             sn = sin(axes.theta);
    1465         } else {
    1466             Rmaj = Rmin = 5.0;
    1467             cs = 1.0;
    1468             sn = 0.0;
    1469             Xo = source->peak->xf;
    1470             Yo = source->peak->yf;
    1471         }
    1472 
    1473         unsigned short int flagMask = 0x01;
    1474         for (int j = 0; j < 8; j++) {
    1475             if (source->mode & flagMask) {
    1476                 overlayE[NoverlayE].type = KII_OVERLAY_LINE;
    1477                 overlayE[NoverlayE].x = Xo;
    1478                 overlayE[NoverlayE].y = Yo;
    1479 
    1480                 float phi = j*M_PI/4.0;
    1481                 overlayE[NoverlayE].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
    1482                 overlayE[NoverlayE].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
    1483                 overlayE[NoverlayE].angle = 0;
    1484                 overlayE[NoverlayE].text = NULL;
    1485                 NoverlayE ++;
    1486                 CHECK_REALLOCATE (overlayE, KiiOverlay, NOVERLAYE, NoverlayE, 100);
    1487             }
    1488             flagMask <<= 1;
    1489 
    1490             if (source->mode & flagMask) {
    1491                 overlayO[NoverlayO].type = KII_OVERLAY_LINE;
    1492                 overlayO[NoverlayO].x = Xo + 1;
    1493                 overlayO[NoverlayO].y = Yo;
    1494 
    1495                 float phi = j*M_PI/4.0;
    1496                 overlayO[NoverlayO].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
    1497                 overlayO[NoverlayO].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
    1498                 overlayO[NoverlayO].angle = 0;
    1499                 overlayO[NoverlayO].text = NULL;
    1500                 NoverlayO ++;
    1501                 CHECK_REALLOCATE (overlayO, KiiOverlay, NOVERLAYO, NoverlayO, 100);
    1502             }
    1503             flagMask <<= 1;
    1504         }
     1466        float Xo, Yo, Rmaj, Rmin, cs, sn;
     1467
     1468        pmSource *source = sources->data[i];
     1469        if (source == NULL) continue;
     1470
     1471        pmMoments *moments = source->moments;
     1472        if (0) {
     1473            emoments.x2 = moments->Mxx;
     1474            emoments.y2 = moments->Myy;
     1475            emoments.xy = moments->Mxy;
     1476            Xo = moments->Mx;
     1477            Yo = moments->My;
     1478
     1479            axes = psEllipseMomentsToAxes (emoments, 20.0);
     1480            Rmaj = 2.0*axes.major;
     1481            Rmin = 2.0*axes.minor;
     1482            cs = cos(axes.theta);
     1483            sn = sin(axes.theta);
     1484        } else {
     1485            Rmaj = Rmin = 5.0;
     1486            cs = 1.0;
     1487            sn = 0.0;
     1488            Xo = source->peak->xf;
     1489            Yo = source->peak->yf;
     1490        }
     1491
     1492        unsigned short int flagMask = 0x01;
     1493        for (int j = 0; j < 8; j++) {
     1494            if (source->mode & flagMask) {
     1495                overlayE[NoverlayE].type = KII_OVERLAY_LINE;
     1496                overlayE[NoverlayE].x = Xo;
     1497                overlayE[NoverlayE].y = Yo;
     1498
     1499                float phi = j*M_PI/4.0;
     1500                overlayE[NoverlayE].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
     1501                overlayE[NoverlayE].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
     1502                overlayE[NoverlayE].angle = 0;
     1503                overlayE[NoverlayE].text = NULL;
     1504                NoverlayE ++;
     1505                CHECK_REALLOCATE (overlayE, KiiOverlay, NOVERLAYE, NoverlayE, 100);
     1506            }
     1507            flagMask <<= 1;
     1508
     1509            if (source->mode & flagMask) {
     1510                overlayO[NoverlayO].type = KII_OVERLAY_LINE;
     1511                overlayO[NoverlayO].x = Xo + 1;
     1512                overlayO[NoverlayO].y = Yo;
     1513
     1514                float phi = j*M_PI/4.0;
     1515                overlayO[NoverlayO].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
     1516                overlayO[NoverlayO].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
     1517                overlayO[NoverlayO].angle = 0;
     1518                overlayO[NoverlayO].text = NULL;
     1519                NoverlayO ++;
     1520                CHECK_REALLOCATE (overlayO, KiiOverlay, NOVERLAYO, NoverlayO, 100);
     1521            }
     1522            flagMask <<= 1;
     1523        }
    15051524    }
    15061525
     
    15311550    for (int i = 0; i < sources->n; i++) {
    15321551
    1533         pmSource *source = sources->data[i];
    1534         if (source == NULL) continue;
    1535 
    1536         if (mode) {
    1537             if (keep) {
    1538                 if (!(source->mode & mode)) continue;
    1539             } else {
    1540                 if (source->mode & mode) continue;
    1541             }
    1542         }
    1543 
    1544         pmMoments *moments = source->moments;
    1545         if (moments == NULL) continue;
    1546 
    1547         overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
    1548         overlay[Noverlay].x = moments->Mx;
    1549         overlay[Noverlay].y = moments->My;
    1550 
    1551         emoments.x2 = moments->Mxx;
    1552         emoments.y2 = moments->Myy;
    1553         emoments.xy = moments->Mxy;
    1554 
    1555         axes = psEllipseMomentsToAxes (emoments, 20.0);
    1556 
    1557         overlay[Noverlay].dx = scale*2.0*axes.major;
    1558         overlay[Noverlay].dy = scale*2.0*axes.minor;
    1559         overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
    1560         overlay[Noverlay].text = NULL;
    1561         Noverlay ++;
     1552        pmSource *source = sources->data[i];
     1553        if (source == NULL) continue;
     1554
     1555        if (mode) {
     1556            if (keep) {
     1557                if (!(source->mode & mode)) continue;
     1558            } else {
     1559                if (source->mode & mode) continue;
     1560            }
     1561        }
     1562
     1563        pmMoments *moments = source->moments;
     1564        if (moments == NULL) continue;
     1565
     1566        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
     1567        overlay[Noverlay].x = moments->Mx;
     1568        overlay[Noverlay].y = moments->My;
     1569
     1570        emoments.x2 = moments->Mxx;
     1571        emoments.y2 = moments->Myy;
     1572        emoments.xy = moments->Mxy;
     1573
     1574        axes = psEllipseMomentsToAxes (emoments, 20.0);
     1575
     1576        overlay[Noverlay].dx = scale*2.0*axes.major;
     1577        overlay[Noverlay].dy = scale*2.0*axes.minor;
     1578        overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
     1579        overlay[Noverlay].text = NULL;
     1580        Noverlay ++;
    15621581    }
    15631582
     
    15701589bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources) {
    15711590
    1572     if (!DEBUG && !pmVisualIsVisual()) return true;
     1591    if (!pmVisualTestLevel("psphot.objects.size", 2)) return true;
    15731592
    15741593    int myKapa = psphotKapaChannel (1);
     
    15971616    KapaSection section;
    15981617
    1599     if (!DEBUG && !pmVisualIsVisual()) return true;
     1618    if (!pmVisualTestLevel("psphot.size", 2)) return true;
    16001619
    16011620    int myKapa = psphotKapaChannel (2);
     
    16121631    float Ymin = 1000.0, Ymax = 0.0;
    16131632    {
    1614         int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
    1615         for (int n = 0; n < nRegions; n++) {
    1616 
    1617             char regionName[64];
    1618             snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
    1619             psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
    1620 
    1621             float psfX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
    1622             float psfY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
    1623             float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
    1624             float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
    1625 
    1626             float X0 = psfX - 10.0*psfdX;
    1627             float X1 = psfX + 10.0*psfdX;
    1628             float Y0 = psfY - 10.0*psfdY;
    1629             float Y1 = psfY + 10.0*psfdY;
    1630 
    1631             if (isfinite(X0)) { Xmin = PS_MIN(Xmin, X0); }
    1632             if (isfinite(X1)) { Xmax = PS_MAX(Xmax, X1); }
    1633             if (isfinite(Y0)) { Ymin = PS_MIN(Ymin, Y0); }
    1634             if (isfinite(Y1)) { Ymax = PS_MAX(Ymax, Y1); }
    1635         }
     1633        int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
     1634        for (int n = 0; n < nRegions; n++) {
     1635
     1636            char regionName[64];
     1637            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
     1638            psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
     1639
     1640            float psfX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
     1641            float psfY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
     1642            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
     1643            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
     1644
     1645            float X0 = psfX - 10.0*psfdX;
     1646            float X1 = psfX + 10.0*psfdX;
     1647            float Y0 = psfY - 10.0*psfdY;
     1648            float Y1 = psfY + 10.0*psfdY;
     1649
     1650            if (isfinite(X0)) { Xmin = PS_MIN(Xmin, X0); }
     1651            if (isfinite(X1)) { Xmax = PS_MAX(Xmax, X1); }
     1652            if (isfinite(Y0)) { Ymin = PS_MIN(Ymin, Y0); }
     1653            if (isfinite(Y1)) { Ymax = PS_MAX(Ymax, Y1); }
     1654        }
    16361655    }
    16371656    Xmin = PS_MAX(Xmin, -0.1);
     
    16771696    int nCR  = 0;
    16781697    for (int i = 0; i < sources->n; i++) {
    1679         pmSource *source = sources->data[i];
    1680         if (source->moments == NULL) continue;
     1698        pmSource *source = sources->data[i];
     1699        if (source->moments == NULL) continue;
    16811700
    16821701        // only plot the measured sources...
    1683         if (!(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED)) continue;
    1684 
    1685         if (source->mode & PM_SOURCE_MODE_CR_LIMIT) {
    1686             xCR->data.F32[nCR] = source->moments->Mxx;
    1687             yCR->data.F32[nCR] = source->moments->Myy;
    1688             mCR->data.F32[nCR] = -2.5*log10(source->moments->Sum);
    1689             sCR->data.F32[nCR] = source->extNsigma;
    1690             nCR++;
    1691         }
    1692         if (source->mode & PM_SOURCE_MODE_SATSTAR) {
    1693             xSAT->data.F32[nSAT] = source->moments->Mxx;
    1694             ySAT->data.F32[nSAT] = source->moments->Myy;
    1695             mSAT->data.F32[nSAT] = -2.5*log10(source->moments->Sum);
    1696             sSAT->data.F32[nSAT] = source->extNsigma;
    1697             nSAT++;
    1698         }
    1699         if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
    1700             xEXT->data.F32[nEXT] = source->moments->Mxx;
    1701             yEXT->data.F32[nEXT] = source->moments->Myy;
    1702             mEXT->data.F32[nEXT] = -2.5*log10(source->moments->Sum);
    1703             sEXT->data.F32[nEXT] = source->extNsigma;
    1704             nEXT++;
    1705             continue;
    1706         }
    1707         if (source->mode & PM_SOURCE_MODE_DEFECT) {
    1708             xDEF->data.F32[nDEF] = source->moments->Mxx;
    1709             yDEF->data.F32[nDEF] = source->moments->Myy;
    1710             mDEF->data.F32[nDEF] = -2.5*log10(source->moments->Sum);
    1711             sDEF->data.F32[nDEF] = source->extNsigma;
    1712             nDEF++;
    1713             continue;
    1714         }
    1715         if (source->errMag > 0.1) {
    1716             xLOW->data.F32[nLOW] = source->moments->Mxx;
    1717             yLOW->data.F32[nLOW] = source->moments->Myy;
    1718             mLOW->data.F32[nLOW] = -2.5*log10(source->moments->Sum);
    1719             sLOW->data.F32[nLOW] = source->extNsigma;
    1720             nLOW++;
    1721             continue;
    1722         }
    1723         xPSF->data.F32[nPSF] = source->moments->Mxx;
    1724         yPSF->data.F32[nPSF] = source->moments->Myy;
    1725         mPSF->data.F32[nPSF] = -2.5*log10(source->moments->Sum);
    1726         sPSF->data.F32[nPSF] = source->extNsigma;
    1727         nPSF++;
     1702        if (!(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED)) continue;
     1703
     1704        if (source->mode & PM_SOURCE_MODE_CR_LIMIT) {
     1705            xCR->data.F32[nCR] = source->moments->Mxx;
     1706            yCR->data.F32[nCR] = source->moments->Myy;
     1707            mCR->data.F32[nCR] = -2.5*log10(source->moments->Sum);
     1708            sCR->data.F32[nCR] = source->extNsigma;
     1709            nCR++;
     1710        }
     1711        if (source->mode & PM_SOURCE_MODE_SATSTAR) {
     1712            xSAT->data.F32[nSAT] = source->moments->Mxx;
     1713            ySAT->data.F32[nSAT] = source->moments->Myy;
     1714            mSAT->data.F32[nSAT] = -2.5*log10(source->moments->Sum);
     1715            sSAT->data.F32[nSAT] = source->extNsigma;
     1716            nSAT++;
     1717        }
     1718        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
     1719            xEXT->data.F32[nEXT] = source->moments->Mxx;
     1720            yEXT->data.F32[nEXT] = source->moments->Myy;
     1721            mEXT->data.F32[nEXT] = -2.5*log10(source->moments->Sum);
     1722            sEXT->data.F32[nEXT] = source->extNsigma;
     1723            nEXT++;
     1724            continue;
     1725        }
     1726        if (source->mode & PM_SOURCE_MODE_DEFECT) {
     1727            xDEF->data.F32[nDEF] = source->moments->Mxx;
     1728            yDEF->data.F32[nDEF] = source->moments->Myy;
     1729            mDEF->data.F32[nDEF] = -2.5*log10(source->moments->Sum);
     1730            sDEF->data.F32[nDEF] = source->extNsigma;
     1731            nDEF++;
     1732            continue;
     1733        }
     1734        if (source->errMag > 0.1) {
     1735            xLOW->data.F32[nLOW] = source->moments->Mxx;
     1736            yLOW->data.F32[nLOW] = source->moments->Myy;
     1737            mLOW->data.F32[nLOW] = -2.5*log10(source->moments->Sum);
     1738            sLOW->data.F32[nLOW] = source->extNsigma;
     1739            nLOW++;
     1740            continue;
     1741        }
     1742        xPSF->data.F32[nPSF] = source->moments->Mxx;
     1743        yPSF->data.F32[nPSF] = source->moments->Myy;
     1744        mPSF->data.F32[nPSF] = -2.5*log10(source->moments->Sum);
     1745        sPSF->data.F32[nPSF] = source->extNsigma;
     1746        nPSF++;
    17281747    }
    17291748
     
    20292048    // draw N circles to outline the clumps
    20302049    {
    2031         KapaSelectSection (myKapa, "MxxMyy");
    2032 
    2033         // draw a circle centered on psfX,Y with size of the psf limit
    2034         psVector *xLimit  = psVectorAlloc (120, PS_TYPE_F32);
    2035         psVector *yLimit  = psVectorAlloc (120, PS_TYPE_F32);
    2036 
    2037         int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
    2038         float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA");
    2039 
    2040         graphdata.color = KapaColorByName ("blue");
    2041         graphdata.style = 0;
    2042 
    2043         graphdata.xmin = Xmin;
    2044         graphdata.ymin = Ymin;
    2045         graphdata.xmax = Xmax;
    2046         graphdata.ymax = Ymax;
    2047         KapaSetLimits (myKapa, &graphdata);
    2048 
    2049         for (int n = 0; n < nRegions; n++) {
    2050 
    2051             char regionName[64];
    2052             snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
    2053             psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
    2054 
    2055             float psfX  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
    2056             float psfY  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
    2057             float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
    2058             float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
    2059             float Rx = psfdX * PSF_CLUMP_NSIGMA;
    2060             float Ry = psfdY * PSF_CLUMP_NSIGMA;
    2061 
    2062             for (int i = 0; i < xLimit->n; i++) {
    2063                 xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX;
    2064                 yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
    2065             }
    2066             KapaPrepPlot (myKapa, xLimit->n, &graphdata);
    2067             KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
    2068             KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
    2069         }
    2070         psFree (xLimit);
    2071         psFree (yLimit);
     2050        KapaSelectSection (myKapa, "MxxMyy");
     2051
     2052        // draw a circle centered on psfX,Y with size of the psf limit
     2053        psVector *xLimit  = psVectorAlloc (120, PS_TYPE_F32);
     2054        psVector *yLimit  = psVectorAlloc (120, PS_TYPE_F32);
     2055
     2056        int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS");
     2057        float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA");
     2058
     2059        graphdata.color = KapaColorByName ("blue");
     2060        graphdata.style = 0;
     2061
     2062        graphdata.xmin = Xmin;
     2063        graphdata.ymin = Ymin;
     2064        graphdata.xmax = Xmax;
     2065        graphdata.ymax = Ymax;
     2066        KapaSetLimits (myKapa, &graphdata);
     2067
     2068        for (int n = 0; n < nRegions; n++) {
     2069
     2070            char regionName[64];
     2071            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
     2072            psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName);
     2073
     2074            float psfX  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
     2075            float psfY  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
     2076            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
     2077            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
     2078            float Rx = psfdX * PSF_CLUMP_NSIGMA;
     2079            float Ry = psfdY * PSF_CLUMP_NSIGMA;
     2080
     2081            for (int i = 0; i < xLimit->n; i++) {
     2082                xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX;
     2083                yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
     2084            }
     2085            KapaPrepPlot (myKapa, xLimit->n, &graphdata);
     2086            KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
     2087            KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
     2088        }
     2089        psFree (xLimit);
     2090        psFree (yLimit);
    20722091    }
    20732092
     
    21082127bool psphotVisualShowResidualImage (pmReadout *readout) {
    21092128
    2110     if (!DEBUG && !pmVisualIsVisual()) return true;
     2129    if (!pmVisualTestLevel("psphot.image.resid", 2)) return true;
    21112130
    21122131    int myKapa = psphotKapaChannel (1);
     
    21242143    float lineX[2], lineY[2];
    21252144
    2126     if (!DEBUG && !pmVisualIsVisual()) return true;
     2145    if (!pmVisualTestLevel("psphot.apresid", 1)) return true;
    21272146
    21282147    int myKapa = psphotKapaChannel (2);
     
    21442163    int n = 0;
    21452164    for (int i = 0; i < sources->n; i++) {
    2146         pmSource *source = sources->data[i];
    2147         if (!source) continue;
    2148         if (source->type != PM_SOURCE_TYPE_STAR) continue;
    2149         if (!isfinite (source->apMag)) continue;
    2150         if (!isfinite (source->psfMag)) continue;
    2151 
    2152         x->data.F32[n] = source->psfMag;
    2153         y->data.F32[n] = source->apMag - source->psfMag;
    2154         dy->data.F32[n] = source->errMag;
    2155         graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
    2156         graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
    2157         graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]);
    2158         graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]);
    2159 
    2160         n++;
     2165        pmSource *source = sources->data[i];
     2166        if (!source) continue;
     2167        if (source->type != PM_SOURCE_TYPE_STAR) continue;
     2168        if (!isfinite (source->apMag)) continue;
     2169        if (!isfinite (source->psfMag)) continue;
     2170
     2171        x->data.F32[n] = source->psfMag;
     2172        y->data.F32[n] = source->apMag - source->psfMag;
     2173        dy->data.F32[n] = source->errMag;
     2174        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
     2175        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
     2176        graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]);
     2177        graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]);
     2178
     2179        n++;
    21612180    }
    21622181    x->n = y->n = dy->n = n;
     
    22422261    Graphdata graphdata;
    22432262
    2244     if (!DEBUG && !pmVisualIsVisual()) return true;
     2263    if (!pmVisualTestLevel("psphot.chisq", 1)) return true;
    22452264
    22462265    int myKapa = psphotKapaChannel (2);
     
    22632282    int n = 0;
    22642283    for (int i = 0; i < sources->n; i++) {
    2265         pmSource *source = sources->data[i];
    2266         if (!source) continue;
    2267         if (source->type != PM_SOURCE_TYPE_STAR) continue;
    2268         if (!source->moments) continue;
    2269         if (!isfinite(source->moments->Sum)) continue;
    2270         if (!source->modelPSF) continue;
    2271         if (!isfinite(source->modelPSF->chisq)) continue;
    2272 
    2273         x->data.F32[n] = -2.5*log10(source->moments->Sum);
    2274         y->data.F32[n] = source->modelPSF->chisq / source->modelPSF->nDOF;
    2275         graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
    2276         graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
    2277         graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]);
    2278         graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]);
    2279 
    2280         fprintf (f, "%d %d %f %f\n", i, n, x->data.F32[n], y->data.F32[n]);
    2281 
    2282         n++;
     2284        pmSource *source = sources->data[i];
     2285        if (!source) continue;
     2286        if (source->type != PM_SOURCE_TYPE_STAR) continue;
     2287        if (!source->moments) continue;
     2288        if (!isfinite(source->moments->Sum)) continue;
     2289        if (!source->modelPSF) continue;
     2290        if (!isfinite(source->modelPSF->chisq)) continue;
     2291
     2292        x->data.F32[n] = -2.5*log10(source->moments->Sum);
     2293        y->data.F32[n] = source->modelPSF->chisq / source->modelPSF->nDOF;
     2294        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
     2295        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
     2296        graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]);
     2297        graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]);
     2298
     2299        fprintf (f, "%d %d %f %f\n", i, n, x->data.F32[n], y->data.F32[n]);
     2300
     2301        n++;
    22832302    }
    22842303    x->n = y->n = n;
     
    23262345    KiiOverlay *overlay;
    23272346
    2328     if (!DEBUG && !pmVisualIsVisual()) return true;
     2347    if (!pmVisualTestLevel("psphot.objects.petro", 2)) return true;
    23292348
    23302349    int kapa = psphotKapaChannel (1);
     
    23362355
    23372356    for (int i = 0; i < sources->n; i++) {
    2338         pmSource *source = sources->data[i];
    2339 
    2340         if (!source) continue;
    2341         if (!source->extpars) continue;
    2342         if (!source->extpars->petProfile) continue;
    2343 
    2344         float petrosianRadius = source->extpars->petrosianRadius;
     2357        pmSource *source = sources->data[i];
     2358
     2359        if (!source) continue;
     2360        if (!source->extpars) continue;
     2361        if (!source->extpars->petProfile) continue;
     2362
     2363        float petrosianRadius = source->extpars->petrosianRadius;
    23452364        psEllipseAxes *axes = &source->extpars->axes;
    23462365
    2347         overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
    2348         overlay[Noverlay].x = source->peak->xf;
    2349         overlay[Noverlay].y = source->peak->yf;
    2350         overlay[Noverlay].dx = 1.0*petrosianRadius;
    2351         overlay[Noverlay].dy = 1.0*petrosianRadius*axes->minor/axes->major;
    2352         overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
    2353         overlay[Noverlay].text = NULL;
    2354         Noverlay ++;
    2355         CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    2356 
    2357         // overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
    2358         // overlay[Noverlay].x = source->peak->xf;
    2359         // overlay[Noverlay].y = source->peak->yf;
    2360         // overlay[Noverlay].dx = 2.0*petrosianRadius;
    2361         // overlay[Noverlay].dy = 2.0*petrosianRadius*axes->minor/axes->major;
    2362         // overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
    2363         // overlay[Noverlay].text = NULL;
    2364         // Noverlay ++;
    2365         // CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     2366        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
     2367        overlay[Noverlay].x = source->peak->xf;
     2368        overlay[Noverlay].y = source->peak->yf;
     2369        overlay[Noverlay].dx = 1.0*petrosianRadius;
     2370        overlay[Noverlay].dy = 1.0*petrosianRadius*axes->minor/axes->major;
     2371        overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
     2372        overlay[Noverlay].text = NULL;
     2373        Noverlay ++;
     2374        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     2375
     2376        // overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
     2377        // overlay[Noverlay].x = source->peak->xf;
     2378        // overlay[Noverlay].y = source->peak->yf;
     2379        // overlay[Noverlay].dx = 2.0*petrosianRadius;
     2380        // overlay[Noverlay].dy = 2.0*petrosianRadius*axes->minor/axes->major;
     2381        // overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
     2382        // overlay[Noverlay].text = NULL;
     2383        // Noverlay ++;
     2384        // CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
    23662385    }
    23672386
Note: See TracChangeset for help on using the changeset viewer.