IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 9, 2010, 8:27:57 AM (16 years ago)
Author:
eugene
Message:

separate penalties for kernels for image 1 and 2, convolve second moments with fwhm to get penalties; separate normalization windows for images 1 and 2; update visual to have facilities like psphot visual; curve of growth analysis for norm window

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20100621/psModules/src/imcombine/pmSubtractionStamps.c

    r28643 r28866  
    5151    psFree(list->y);
    5252    psFree(list->flux);
    53     psFree(list->window);
     53    psFree(list->window1);
     54    psFree(list->window2);
    5455}
    5556
     
    230231    list->y = NULL;
    231232    list->flux = NULL;
    232     list->window = NULL;
    233233    list->normFrac = normFrac;
    234     list->normWindow = 0;
     234    list->window1 = NULL;
     235    list->window2 = NULL;
     236    list->normWindow1 = 0;
     237    list->normWindow2 = 0;
    235238    list->footprint = footprint;
    236239    list->sysErr = sysErr;
     
    253256    out->y = NULL;
    254257    out->flux = NULL;
    255     out->window = psMemIncrRefCounter(in->window);
     258    out->window1 = psMemIncrRefCounter(in->window1);
     259    out->window2 = psMemIncrRefCounter(in->window2);
    256260    out->footprint = in->footprint;
    257     out->normWindow = in->normWindow;
     261    out->normWindow1 = in->normWindow1;
     262    out->normWindow2 = in->normWindow2;
    258263
    259264    for (int i = 0; i < num; i++) {
     
    643648    int size = stamps->footprint; // Size of postage stamps
    644649
    645     psFree (stamps->window);
    646     stamps->window = psKernelAlloc(-size, size, -size, size);
    647     psImageInit(stamps->window->image, 0.0);
     650    psFree (stamps->window1);
     651    stamps->window1 = psKernelAlloc(-size, size, -size, size);
     652    psImageInit(stamps->window1->image, 0.0);
     653
     654    psFree (stamps->window2);
     655    stamps->window2 = psKernelAlloc(-size, size, -size, size);
     656    psImageInit(stamps->window2->image, 0.0);
    648657
    649658    // generate normalizations for each stamp
     
    674683
    675684    // generate the window pixels
    676     double sum = 0.0;                   // Sum inside the window
    677     float maxValue = 0.0;               // Maximum value, for normalisation
     685    double sum1 = 0.0;                   // Sum inside the window
     686    double sum2 = 0.0;                   // Sum inside the window
     687    float maxValue1 = 0.0;               // Maximum value, for normalisation
     688    float maxValue2 = 0.0;               // Maximum value, for normalisation
    678689    for (int y = -size; y <= size; y++) {
    679690        for (int x = -size; x <= size; x++) {
     
    696707            }
    697708            float f1 = stats->robustMedian;
     709
    698710            psStatsInit (stats);
    699711            if (!psVectorStats (stats, flux2, NULL, NULL, 0)) {
     
    702714            float f2 = stats->robustMedian;
    703715
    704             stamps->window->kernel[y][x] = f1 + f2;
     716            stamps->window1->kernel[y][x] = f1;
    705717            if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) {
    706                 sum += stamps->window->kernel[y][x];
    707             }
    708             maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]);
    709         }
    710     }
    711 
    712     psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n",
    713             sum, (1.0 - stamps->normFrac) * sum);
    714     bool done = false;
    715     for (int radius = 1; radius <= size && !done; radius++) {
    716         double within = 0.0;
     718                sum1 += stamps->window1->kernel[y][x];
     719            }
     720            maxValue1 = PS_MAX(maxValue1, stamps->window1->kernel[y][x]);
     721
     722            stamps->window2->kernel[y][x] = f2;
     723            if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) {
     724                sum2 += stamps->window2->kernel[y][x];
     725            }
     726            maxValue2 = PS_MAX(maxValue2, stamps->window2->kernel[y][x]);
     727        }
     728    }
     729
     730    psTrace("psModules.imcombine", 3, "Window total (1): %f, threshold: %f\n", sum1, (1.0 - stamps->normFrac) * sum1);
     731    psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2);
     732
     733# if (0)
     734    // this block attempts to calculate the radius based on the first radial moment
     735    bool done1 = false;
     736    bool done2 = false;
     737    double prior1 = 0.0;
     738    double prior2 = 0.0;
     739    for (int y = -size; y <= size; y++) {
     740        for (int x = -size; x <= size; x++) {
     741            float r = hypot(x, y);
     742            Sr1 += r * stamps->window1->kernel[y][x];
     743            Sr2 += r * stamps->window2->kernel[y][x];
     744            Sf1 += stamps->window1->kernel[y][x];
     745            Sf2 += stamps->window2->kernel[y][x];
     746        }
     747    }
     748   
     749    float R1 = Sr1 / Sf1;
     750    float R2 = Sr2 / Sf2;
     751
     752    stamps->normWindow1 = 2.5*R1;
     753    stamps->normWindow1 = 2.5*R2;
     754# else
     755    // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent).
     756    // It did not do very well (though a true curve-of-growth analysis might be better...)
     757    bool done1 = false;
     758    bool done2 = false;
     759    double prior1 = 0.0;
     760    double prior2 = 0.0;
     761    double delta1o = 1.0;
     762    double delta2o = 1.0;
     763    for (int radius = 1; radius <= size && !(done1 && done2); radius++) {
     764        double within1 = 0.0;
     765        double within2 = 0.0;
    717766        for (int y = -radius; y <= radius; y++) {
    718767            for (int x = -radius; x <= radius; x++) {
    719768                if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
    720                     within += stamps->window->kernel[y][x];
     769                    within1 += stamps->window1->kernel[y][x];
    721770                }
    722             }
    723         }
    724         psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within);
    725         if (within > (1.0 - stamps->normFrac) * sum) {
    726             stamps->normWindow = radius;
    727             done = true;
    728         }
    729     }
    730 
    731     psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow);
    732     if (stamps->normWindow == 0 || stamps->normWindow >= size) {
    733         psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size.");
     771                if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
     772                    within2 += stamps->window2->kernel[y][x];
     773                }
     774            }
     775        }
     776        double delta1 = (within1 - prior1) / within1;
     777        if (!done1 && (fabs(delta1) < stamps->normFrac)) {
     778            // interpolate to the radius at which delta2 is normFrac:
     779            stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1);
     780            fprintf (stderr, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1);
     781            done1 = true;
     782        }
     783        double delta2 = (within2 - prior2) / within2;
     784        if (!done2 && (fabs(delta2) < stamps->normFrac)) {
     785            // interpolate to the radius at which delta2 is normFrac:
     786            stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2);
     787            fprintf (stderr, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2);
     788            done2 = true;
     789        }
     790        psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2);
     791
     792        prior1 = within1;
     793        prior2 = within2;
     794        delta1o = delta1;
     795        delta2o = delta2;
     796
     797        // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) {
     798        //     stamps->normWindow1 = radius;
     799        //     done1 = true;
     800        // }
     801        // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) {
     802        //     stamps->normWindow2 = radius;
     803        //     done2 = true;
     804        // }
     805
     806    }
     807# endif
     808
     809    psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2);
     810    if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) {
     811        psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1).");
     812        return false;
     813    }
     814    if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) {
     815        psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2).");
    734816        return false;
    735817    }
     
    738820    for (int y = -size; y <= size; y++) {
    739821        for (int x = -size; x <= size; x++) {
    740             stamps->window->kernel[y][x] /= maxValue;
    741         }
    742     }
    743 
    744 #if 0
     822            stamps->window1->kernel[y][x] /= maxValue1;
     823        }
     824    }
     825    // re-normalize so chisquare values are sensible
     826    for (int y = -size; y <= size; y++) {
     827        for (int x = -size; x <= size; x++) {
     828            stamps->window2->kernel[y][x] /= maxValue2;
     829        }
     830    }
     831
     832#if 1
    745833    {
    746         psFits *fits = psFitsOpen ("window.fits", "w");
    747         psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL);
     834        psFits *fits = NULL;
     835        fits = psFitsOpen ("window1.fits", "w");
     836        psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL);
     837        psFitsClose (fits);
     838        fits = psFitsOpen ("window2.fits", "w");
     839        psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL);
    748840        psFitsClose (fits);
    749841    }
     
    752844    psFree (stats);
    753845    psFree (flux1);
    754     psFree(flux2);
     846    psFree (flux2);
    755847    psFree (norm1);
    756848    psFree (norm2);
    757849    return true;
     850}
     851
     852static pthread_mutex_t getPenaltiesMutex = PTHREAD_MUTEX_INITIALIZER;
     853
     854// kernels->penalty is an overall scaling factor (user-supplied)
     855bool pmSubtractionKernelPenaltiesStamp(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels)
     856{
     857    // we only need the penalties if we are doing dual convolution
     858    if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) return true;
     859
     860    // we only calculate the penalties once.
     861    if (kernels->havePenalties) return true;
     862
     863    // in a threaded context, only one thread can calculate the penalties.  attempt to grab a
     864    // mutex before continuing
     865    pthread_mutex_lock(&getPenaltiesMutex);
     866
     867    // did someone else already get the mutex and do this?
     868    if (kernels->havePenalties) {
     869        pthread_mutex_unlock(&getPenaltiesMutex);
     870        return true;
     871    }
     872
     873    for (int i = 0; i < kernels->num; i++) {
     874        pmSubtractionKernelPenalties(stamp, kernels, i);
     875    }
     876
     877    kernels->havePenalties = true;
     878    pthread_mutex_unlock(&getPenaltiesMutex);
     879    return true;
     880}
     881
     882# define EMPIRICAL 0
     883
     884// kernels->penalty is an overall scaling factor (user-supplied)
     885bool pmSubtractionKernelPenalties(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels, int index)
     886{
     887    float penalty1, penalty2;
     888    float fwhm1, fwhm2;
     889
     890    // XXX this is annoyingly hack-ish
     891    pmSubtractionGetFWHMs(&fwhm1, &fwhm2);
     892
     893    if (EMPIRICAL) {
     894        psKernel *convolution1 = stamp->convolutions1->data[index];
     895        penalty1 = pmSubtractionKernelPenaltySingle(convolution1);
     896
     897        psKernel *convolution2 = stamp->convolutions2->data[index];
     898        penalty2 = pmSubtractionKernelPenaltySingle(convolution2);
     899    } else {
     900        pmSubtractionKernelPreCalc *kernel = kernels->preCalc->data[index];
     901        float M2 = pmSubtractionKernelPenaltySingle(kernel->kernel);
     902
     903        penalty1 = M2 * PS_SQR(fwhm1 / 2.35); // rescale the unconvolved second-moment by the image second moment
     904        penalty2 = M2 * PS_SQR(fwhm2 / 2.35); // rescale the unconvolved second-moment by the image second moment
     905    }
     906    kernels->penalties1->data.F32[index] = kernels->penalty * penalty1;
     907    psAssert (isfinite(kernels->penalties1->data.F32[index]), "invalid penalty");
     908
     909    kernels->penalties2->data.F32[index] = kernels->penalty * penalty2;
     910    psAssert (isfinite(kernels->penalties2->data.F32[index]), "invalid penalty");
     911
     912    fprintf(stderr, "penalty1: %f, penalty2: %f\n", penalty1, penalty2);
     913
     914    return true;
     915}
     916
     917float pmSubtractionKernelPenaltySingle(psKernel *kernel)
     918{
     919    // Calculate moments
     920    double penalty = 0.0;                   // Moment, for penalty
     921    double sum = 0.0, sum2 = 0.0;           // Sum of kernel component
     922    float min = INFINITY, max = -INFINITY;  // Minimum and maximum kernel value
     923    for (int v = kernel->yMin; v <= kernel->yMax; v++) {
     924        for (int u = kernel->xMin; u <= kernel->xMax; u++) {
     925            double value = kernel->kernel[v][u];
     926            double value2 = PS_SQR(value);
     927            sum += value;
     928            sum2 += value2;
     929            penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v)));
     930            min = PS_MIN(value, min);
     931            max = PS_MAX(value, max);
     932        }
     933    }
     934    penalty *= 1.0 / sum2;
     935
     936    if (0) {
     937        fprintf(stderr, "min: %lf, max: %lf, moment: %lf\n", min, max, penalty);
     938        // psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, penalty);
     939    }
     940
     941    return penalty;
    758942}
    759943
Note: See TracChangeset for help on using the changeset viewer.