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/psModules

    • Property svn:mergeinfo deleted
  • branches/sc_branches/trunkTest/psModules/src/imcombine/pmSubtractionStamps.c

    r27402 r29060  
    77#include <pslib.h>
    88
     9#include "pmErrorCodes.h"
     10#include "pmHDU.h"
     11#include "pmFPA.h"
     12
    913// All these includes required to get stamps out of an array of pmSources
    10 #include "pmMoments.h"
     14#include "pmTrend2D.h"
     15#include "pmResiduals.h"
     16#include "pmGrowthCurve.h"
    1117#include "pmSpan.h"
     18#include "pmFootprintSpans.h"
    1219#include "pmFootprint.h"
    1320#include "pmPeaks.h"
    14 #include "pmResiduals.h"
    15 #include "pmHDU.h"
    16 #include "pmFPA.h"
    17 #include "pmGrowthCurve.h"
    18 #include "pmTrend2D.h"
    19 #include "pmPSF.h"
     21#include "pmMoments.h"
     22#include "pmModelFuncs.h"
    2023#include "pmModel.h"
     24#include "pmSourceMasks.h"
     25#include "pmSourceExtendedPars.h"
     26#include "pmSourceDiffStats.h"
    2127#include "pmSource.h"
    22 #include "pmErrorCodes.h"
    2328
    2429#include "pmSubtraction.h"
     
    4651    psFree(list->y);
    4752    psFree(list->flux);
    48     psFree(list->window);
     53    psFree(list->window1);
     54    psFree(list->window2);
    4955}
    5056
     
    225231    list->y = NULL;
    226232    list->flux = NULL;
    227     list->window = NULL;
    228233    list->normFrac = normFrac;
    229     list->normWindow = 0;
     234    list->window1 = NULL;
     235    list->window2 = NULL;
     236    list->normWindow1 = 0;
     237    list->normWindow2 = 0;
    230238    list->footprint = footprint;
    231239    list->sysErr = sysErr;
     
    248256    out->y = NULL;
    249257    out->flux = NULL;
    250     out->window = psMemIncrRefCounter(in->window);
     258    out->window1 = psMemIncrRefCounter(in->window1);
     259    out->window2 = psMemIncrRefCounter(in->window2);
    251260    out->footprint = in->footprint;
    252     out->normWindow = in->normWindow;
     261    out->normWindow1 = in->normWindow1;
     262    out->normWindow2 = in->normWindow2;
    253263
    254264    for (int i = 0; i < num; i++) {
     
    638648    int size = stamps->footprint; // Size of postage stamps
    639649
    640     psFree (stamps->window);
    641     stamps->window = psKernelAlloc(-size, size, -size, size);
    642     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);
    643657
    644658    // generate normalizations for each stamp
     
    669683
    670684    // generate the window pixels
    671     double sum = 0.0;                   // Sum inside the window
    672     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
    673689    for (int y = -size; y <= size; y++) {
    674690        for (int x = -size; x <= size; x++) {
     
    691707            }
    692708            float f1 = stats->robustMedian;
     709
    693710            psStatsInit (stats);
    694711            if (!psVectorStats (stats, flux2, NULL, NULL, 0)) {
     
    697714            float f2 = stats->robustMedian;
    698715
    699             stamps->window->kernel[y][x] = f1 + f2;
     716            stamps->window1->kernel[y][x] = f1;
    700717            if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) {
    701                 sum += stamps->window->kernel[y][x];
    702             }
    703             maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]);
    704         }
    705     }
    706 
    707     psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n",
    708             sum, (1.0 - stamps->normFrac) * sum);
    709     bool done = false;
    710     for (int radius = 1; radius <= size && !done; radius++) {
    711         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;
    712766        for (int y = -radius; y <= radius; y++) {
    713767            for (int x = -radius; x <= radius; x++) {
    714768                if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
    715                     within += stamps->window->kernel[y][x];
     769                    within1 += stamps->window1->kernel[y][x];
    716770                }
    717             }
    718         }
    719         psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within);
    720         if (within > (1.0 - stamps->normFrac) * sum) {
    721             stamps->normWindow = radius;
    722             done = true;
    723         }
    724     }
    725 
    726     psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow);
    727     if (stamps->normWindow == 0 || stamps->normWindow >= size) {
    728         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).");
    729816        return false;
    730817    }
     
    733820    for (int y = -size; y <= size; y++) {
    734821        for (int x = -size; x <= size; x++) {
    735             stamps->window->kernel[y][x] /= maxValue;
     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;
    736829        }
    737830    }
     
    739832#if 0
    740833    {
    741         psFits *fits = psFitsOpen ("window.fits", "w");
    742         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);
    743840        psFitsClose (fits);
    744841    }
     
    747844    psFree (stats);
    748845    psFree (flux1);
    749     psFree(flux2);
     846    psFree (flux2);
    750847    psFree (norm1);
    751848    psFree (norm2);
    752849    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    bool zeroNull = false;
     894    int uOrder = kernels->u->data.S32[index];
     895    int vOrder = kernels->v->data.S32[index];
     896    if (uOrder % 2 == 0 && vOrder % 2 == 0) zeroNull = true;
     897
     898    if (EMPIRICAL) {
     899        psKernel *convolution1 = stamp->convolutions1->data[index];
     900        penalty1 = pmSubtractionKernelPenaltySingle(convolution1, zeroNull);
     901
     902        psKernel *convolution2 = stamp->convolutions2->data[index];
     903        penalty2 = pmSubtractionKernelPenaltySingle(convolution2, zeroNull);
     904    } else {
     905        pmSubtractionKernelPreCalc *kernel = kernels->preCalc->data[index];
     906        float M2 = pmSubtractionKernelPenaltySingle(kernel->kernel, zeroNull);
     907
     908        penalty1 = M2 + PS_SQR(fwhm1 / 2.35); // rescale the unconvolved second-moment by the image second moment
     909        penalty2 = M2 + PS_SQR(fwhm2 / 2.35); // rescale the unconvolved second-moment by the image second moment
     910    }
     911    kernels->penalties1->data.F32[index] = kernels->penalty * penalty1;
     912    psAssert (isfinite(kernels->penalties1->data.F32[index]), "invalid penalty");
     913
     914    kernels->penalties2->data.F32[index] = kernels->penalty * penalty2;
     915    psAssert (isfinite(kernels->penalties2->data.F32[index]), "invalid penalty");
     916
     917    fprintf(stderr, "penalty1: %f, penalty2: %f\n", penalty1, penalty2);
     918
     919    return true;
     920}
     921
     922float pmSubtractionKernelPenaltySingle(psKernel *kernel, bool zeroNull)
     923{
     924    // Calculate moments
     925    double penalty = 0.0;                   // Moment, for penalty
     926    double sum = 0.0, sum2 = 0.0;           // Sum of kernel component
     927    float min = INFINITY, max = -INFINITY;  // Minimum and maximum kernel value
     928    for (int v = kernel->yMin; v <= kernel->yMax; v++) {
     929        for (int u = kernel->xMin; u <= kernel->xMax; u++) {
     930            double value = kernel->kernel[v][u];
     931            if (false && zeroNull && (u == 0) && (v == 0)) {
     932                value += 1.0;
     933            }
     934            double value2 = PS_SQR(value);
     935            sum += value;
     936            sum2 += value2;
     937            penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v)));
     938            min = PS_MIN(value, min);
     939            max = PS_MAX(value, max);
     940        }
     941    }
     942    penalty *= 1.0 / sum2;
     943
     944    if (1) {
     945        fprintf(stderr, "min: %lf, max: %lf, moment: %lf, flux^2: %lf\n", min, max, penalty, sum2);
     946        // psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, penalty);
     947    }
     948
     949    return penalty;
    753950}
    754951
Note: See TracChangeset for help on using the changeset viewer.