IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 25, 2010, 9:45:07 PM (15 years ago)
Author:
watersc1
Message:

Merge of czw_branch/20100817 into trunk. This includes the non-linearity correction application code.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/psModules/src/detrend/pmNonLinear.c

    r12696 r29833  
    1010#include "pmNonLinear.h"
    1111
     12psF32 pmNonLinearityMeasureNoisy(psF32 flux, psVector *correction_fluxes, psVector *correction_factors);
    1213pmReadout *pmNonLinearityPolynomial(pmReadout *inputReadout, const psPolynomial1D *input1DPoly)
    1314{
     
    2728
    2829// set the bin closest to the corresponding value. 
    29 #define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE) { \
    30         psVectorBinaryDisectResult result; \
    31         psScalar tmpScalar; \
    32         tmpScalar.type.type = PS_TYPE_F32; \
    33         tmpScalar.data.F32 = (VALUE); \
    34         RESULT = psVectorBinaryDisect (&result, VECTOR, &tmpScalar); \
    35         switch (result) { \
    36           case PS_BINARY_DISECT_PASS: \
    37             break; \
    38           case PS_BINARY_DISECT_OUTSIDE_RANGE: \
    39             numPixels ++; \
    40             break; \
    41           case PS_BINARY_DISECT_INVALID_INPUT: \
    42           case PS_BINARY_DISECT_INVALID_TYPE: \
    43             psAbort ("programming error"); \
    44             break; \
     30#define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE) {                       \
     31        psVectorBinaryDisectResult result;                              \
     32        psScalar tmpScalar;                                             \
     33        tmpScalar.type.type = PS_TYPE_F32;                              \
     34        tmpScalar.data.F32 = (VALUE);                                   \
     35        RESULT = psVectorBinaryDisect (&result, VECTOR, &tmpScalar);    \
     36        switch (result) {                                               \
     37          case PS_BINARY_DISECT_PASS:                                   \
     38            break;                                                      \
     39          case PS_BINARY_DISECT_OUTSIDE_RANGE:                          \
     40            numPixels ++;                                               \
     41            break;                                                      \
     42          case PS_BINARY_DISECT_INVALID_INPUT:                          \
     43          case PS_BINARY_DISECT_INVALID_TYPE:                           \
     44            psAbort ("programming error");                              \
     45            break;                                                      \
    4546        } }
     47
     48
     49# define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE) {       \
     50        float dX, dY, Xo, Yo, Xt;                                       \
     51        if (BIN == BOUNDS->n - 1) {                                     \
     52            dX = 0.5*(BOUNDS->data.F32[BIN+1] - BOUNDS->data.F32[BIN-1]); \
     53            dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN-1];       \
     54            Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
     55            Yo = VECTOR->data.F32[BIN];                                 \
     56        } else {                                                        \
     57            dX = 0.5*(BOUNDS->data.F32[BIN+2] - BOUNDS->data.F32[BIN]); \
     58            dY = VECTOR->data.F32[BIN+1] - VECTOR->data.F32[BIN];       \
     59            Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
     60            Yo = VECTOR->data.F32[BIN];                                 \
     61        }                                                               \
     62        if (dY != 0) {                                                  \
     63            Xt = (VALUE - Yo)*dX/dY + Xo;                               \
     64        } else {                                                        \
     65            Xt = Xo;                                                    \
     66        }                                                               \
     67        Xt = PS_MIN (BOUNDS->data.F32[BIN+1], PS_MAX(BOUNDS->data.F32[BIN], Xt)); \
     68        psTrace("pmNonLinear", 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \
     69                Xo, Yo, dX, dY, Xt, VALUE);                             \
     70        RESULT = Xt; }
    4671
    4772pmReadout *pmNonLinearityLookup(pmReadout *inputReadout, const psVector *inFlux, const psVector *outFlux)
     
    92117    return inputReadout;
    93118}
     119
     120bool pmNonLinearityApply(pmReadout *inputReadout, psArray *Ltab)
     121{
     122    PS_ASSERT_PTR_NON_NULL(inputReadout, false);
     123    PS_ASSERT_PTR_NON_NULL(inputReadout->image, false);
     124    PS_ASSERT_IMAGE_TYPE(inputReadout->image, PS_TYPE_F32, false);
     125    PS_ASSERT_PTR_NON_NULL(Ltab, false);
     126
     127    psTimerStart ("nonlinear");
     128
     129    psS32 numSamples = 39;
     130    psS32 numBorder  = 10;
     131
     132    //  psS32 tableSize = Ltab->n;
     133
     134    psImage *image = inputReadout->image;
     135
     136    // Load default data.
     137    psVector *default_row_correction_fluxes = psVectorAlloc(numSamples,PS_TYPE_F32);
     138    psVector *default_col_correction_fluxes = psVectorAlloc(numSamples,PS_TYPE_F32);
     139
     140    psVector *default_row_correction_factors = psVectorAlloc(numSamples,PS_TYPE_F32);
     141    psVector *default_col_correction_factors = psVectorAlloc(numSamples,PS_TYPE_F32);
     142
     143    // pre-allocate the correction vectors
     144    psVector *row_correction_fluxes  = NULL;
     145    psVector *col_correction_fluxes  = NULL;
     146    psVector *row_correction_factors = NULL;
     147    psVector *col_correction_factors = NULL;
     148
     149    int n = 0;
     150    int m = 0;
     151    for (int k = 0; k < Ltab->n; k++) { // Begin load default tables
     152        psMetadata *row = Ltab->data[k];       
     153        if (psMetadataLookupS32(NULL,row,"POSITION") != -1) {
     154            continue;
     155        }
     156        if (psMetadataLookupS32(NULL,row,"DIRECTION") == 0) {
     157            psVectorSet(default_row_correction_fluxes,n,psMetadataLookupF32(NULL,row,"FLUX"));
     158            psVectorSet(default_row_correction_factors,n,psMetadataLookupF32(NULL,row,"FACTOR"));
     159            n++;
     160        }
     161        else {
     162            psVectorSet(default_col_correction_fluxes,m,psMetadataLookupF32(NULL,row,"FLUX"));
     163            psVectorSet(default_col_correction_factors,m,psMetadataLookupF32(NULL,row,"FACTOR"));
     164            m++;
     165        }
     166    } // End load default tables
     167 
     168    psLogMsg ("psModules", PS_LOG_MINUTIA, "load default data from table: %f sec\n", psTimerMark ("nonlinear"));
     169
     170    // pre-allocate arrays with the correction vectors for the borders
     171    psArray *x_lo_flux = psArrayAlloc(numBorder);
     172    psArray *x_hi_flux = psArrayAlloc(numBorder);
     173    psArray *y_lo_flux = psArrayAlloc(numBorder);
     174    psArray *y_hi_flux = psArrayAlloc(numBorder);
     175
     176    psArray *x_lo_fact = psArrayAlloc(numBorder);
     177    psArray *x_hi_fact = psArrayAlloc(numBorder);
     178    psArray *y_lo_fact = psArrayAlloc(numBorder);
     179    psArray *y_hi_fact = psArrayAlloc(numBorder);
     180    for (int i = 0; i < numBorder; i++) {
     181        // pre-allocate the correction vectors
     182        x_lo_flux->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     183        x_hi_flux->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     184        y_lo_flux->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     185        y_hi_flux->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     186
     187        x_lo_fact->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     188        x_hi_fact->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     189        y_lo_fact->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     190        y_hi_fact->data[i] = psVectorAllocEmpty(numSamples,PS_TYPE_F32);
     191    }   
     192
     193    // parse out the full table:
     194    for (int k = 0; k < Ltab->n; k++) {
     195        psMetadata *row = Ltab->data[k];       
     196        int dir = psMetadataLookupS32(NULL,row,"DIRECTION");
     197        int pos = psMetadataLookupS32(NULL,row,"POSITION");
     198
     199        psVector *fluxVector = NULL;
     200        psVector *factVector = NULL;
     201
     202        int seq = -1;
     203        if ((dir == 0) && (pos < image->numCols/2)) {
     204          seq = pos ;
     205            if (seq < 0) continue;
     206            fluxVector = x_lo_flux->data[seq];
     207            factVector = x_lo_fact->data[seq];
     208        }
     209        if ((dir == 0) && (pos > image->numCols/2)) {
     210            seq = pos + numBorder - image->numCols;
     211            if (seq >= image->numCols) continue;
     212            fluxVector = x_hi_flux->data[seq];
     213            factVector = x_hi_fact->data[seq];
     214        }
     215        if ((dir == 1) && (pos < image->numRows/2)) {
     216            seq = pos;
     217            if (seq < 0) continue;
     218            fluxVector = y_lo_flux->data[seq];
     219            factVector = y_lo_fact->data[seq];
     220        }
     221        if ((dir == 1) && (pos > image->numRows/2)) {
     222            seq = pos + numBorder - image->numRows;
     223            if (seq >= image->numRows) continue;
     224            fluxVector = y_hi_flux->data[seq];
     225            factVector = y_hi_fact->data[seq];
     226        }
     227
     228        float flux = psMetadataLookupF32(NULL,row,"FLUX");
     229        float factor = psMetadataLookupF32(NULL,row,"FACTOR");
     230
     231        psVectorAppend(fluxVector, flux);
     232        psVectorAppend(factVector, factor);
     233    }
     234    psLogMsg ("psModules", PS_LOG_MINUTIA, "load border data from table: %f sec\n", psTimerMark ("nonlinear"));
     235
     236    for (int i = 0; i < image->numRows; i++) { // Loop over rows : note: problem with discontinuity here
     237        row_correction_fluxes = NULL;
     238        if (i < numBorder) {
     239            row_correction_fluxes  = y_lo_flux->data[i];
     240            row_correction_factors = y_lo_fact->data[i];
     241        }
     242        if (i > image->numRows - numBorder) {
     243            row_correction_fluxes  = y_hi_flux->data[i + numBorder - image->numRows];
     244            row_correction_factors = y_hi_fact->data[i + numBorder - image->numRows];
     245        }
     246        if (row_correction_fluxes == NULL) {
     247          row_correction_factors = default_row_correction_factors;
     248            row_correction_fluxes = default_row_correction_fluxes;
     249        }
     250
     251        for (int j = 0; j < image->numCols; j++) { // Loop over columns
     252            col_correction_fluxes = NULL;
     253            if (j < numBorder) {
     254                col_correction_fluxes  = x_lo_flux->data[j];
     255                col_correction_factors = x_lo_fact->data[j];
     256            }
     257            if (j > image->numCols - numBorder) {
     258                col_correction_fluxes  = x_hi_flux->data[j + numBorder - image->numCols];
     259                col_correction_factors = x_hi_fact->data[j + numBorder - image->numCols];
     260            }
     261            if (col_correction_fluxes == NULL) {
     262              col_correction_factors = default_col_correction_factors;
     263              col_correction_fluxes = default_col_correction_fluxes;
     264            }
     265
     266            // Calculate correction factor contribution for this pixel.
     267            psF32 factor_row = pmNonLinearityMeasure(image->data.F32[i][j], row_correction_fluxes,row_correction_factors);
     268            psF32 factor_col = pmNonLinearityMeasure(image->data.F32[i][j], col_correction_fluxes,col_correction_factors);
     269#if (0)
     270            if (((i == 200)&&(j == 200))||((i == 9)&&(j == 5))) { // Print out if we're looking at a test case.
     271              psF32 factor_row = pmNonLinearityMeasureNoisy(image->data.F32[i][j], row_correction_fluxes,row_correction_factors);
     272              psF32 factor_col = pmNonLinearityMeasureNoisy(image->data.F32[i][j], col_correction_fluxes,col_correction_factors);
     273             
     274                psTrace("psModules.nonlin",6,"Linearity: %d %d %s %f %f %f %d %d\n",i,j,
     275                        psMetadataLookupStr(NULL,inputReadout->parent->concepts,"CELL.NAME"),
     276                        image->data.F32[i][j],factor_row,factor_col,numBorder,numSamples);
     277                psTrace("psModules.nonlin",6,"Linearity: R: %d %d %d C: %d %d %d\n",
     278                        i,(i < numBorder),(image->numRows - i),
     279                        j,(j < numBorder),(image->numCols - j));
     280
     281                psTrace("psModules.nonlin",6,"Linearity: V: ");
     282                for (int k = 0; k < numSamples; k++) {
     283                    psTrace("psModules.nonlin",6,"(%f %f) (%f %f) DDDD> (%f %f) (%f %f)",
     284                            col_correction_fluxes->data.F32[k],col_correction_factors->data.F32[k],
     285                            row_correction_fluxes->data.F32[k],row_correction_factors->data.F32[k],
     286                            default_col_correction_fluxes->data.F32[k],default_col_correction_factors->data.F32[k],
     287                            default_row_correction_fluxes->data.F32[k],default_row_correction_factors->data.F32[k]);
     288                }
     289                psTrace("psModules.nonlin",6,"\n");
     290            } // End Test case
     291#endif
     292            // Apply correction to image data
     293#if (0)
     294            if (((i == 200)&&(j == 200))||((i == 9)&&(j == 5))) { // Print out if we're looking at a test case.
     295              psTrace("psModules.nonlin",4,"Applied Linearity Correction: %s %d %d : %f %f -> %f\n",
     296                      psMetadataLookupStr(NULL,inputReadout->parent->concepts,"CELL.NAME"),
     297                      i,j,image->data.F32[i][j],(factor_row + factor_col) / 2.0,
     298                      image->data.F32[i][j] + (factor_row + factor_col) / 2.0);
     299            }
     300# endif
     301            image->data.F32[i][j] = image->data.F32[i][j] - ( factor_row + factor_col ) / 2.0;
     302
     303        } // End loop over columns
     304    } // End loop over rows
     305    psLogMsg ("psModules", PS_LOG_MINUTIA, "apply correction: %f sec\n", psTimerMark ("nonlinear"));
     306
     307    psFree(x_lo_flux);
     308    psFree(x_hi_flux);
     309    psFree(y_lo_flux);
     310    psFree(y_hi_flux);
     311
     312    psFree(x_lo_fact);
     313    psFree(x_hi_fact);
     314    psFree(y_lo_fact);
     315    psFree(y_hi_fact);
     316
     317    psFree(default_row_correction_fluxes);
     318    psFree(default_row_correction_factors);
     319    psFree(default_col_correction_fluxes);
     320    psFree(default_col_correction_factors);
     321 
     322    return(true);
     323}
     324
     325psF32 pmNonLinearityMeasure(psF32 flux, psVector *correction_fluxes, psVector *correction_factors) {
     326    //  psS32 numPixels = 0;
     327    psF32 result = 0;
     328    psU32 bin = 0;
     329
     330    bin = correction_fluxes->n - 1;
     331    if (flux < correction_fluxes->data.F32[0]) {
     332        return(0.0);
     333    }
     334/*     if (flux > correction_fluxes->data.F32[bin]) { */
     335/*      return(0.0); */
     336/*     } */
     337 
     338    for (int i = 0; i < correction_fluxes->n - 1; i++) {
     339        if ((flux >= correction_fluxes->data.F32[i])&&
     340            (flux <  correction_fluxes->data.F32[i+1])) {
     341            result = correction_factors->data.F32[i] +
     342                (flux - correction_fluxes->data.F32[i]) *
     343                ((correction_factors->data.F32[i+1] - correction_factors->data.F32[i]) /
     344                 (correction_fluxes->data.F32[i+1] - correction_fluxes->data.F32[i]));
     345            continue;
     346        }
     347    }
     348
     349/*   PS_BIN_FOR_VALUE(bin,correction_fluxes,flux); */
     350/*   if ((bin < 0)||(bin > correction_fluxes->n)) { */
     351/*     return(1.0); */
     352/*   } */
     353 
     354/*   PS_BIN_INTERPOLATE(result,correction_fluxes,correction_factors,bin,flux); */
     355    if (!isfinite(result)) {
     356        result = 0.0;
     357    }
     358/*     if (result <= 0) { */
     359/*      result = 1.0; */
     360/*     } */
     361    return(result);
     362}
     363
     364psF32 pmNonLinearityMeasureNoisy(psF32 flux, psVector *correction_fluxes, psVector *correction_factors) {
     365    //  psS32 numPixels = 0;
     366    psF32 result = 0;
     367    psU32 bin = 0;
     368
     369    bin = correction_fluxes->n - 1;
     370    psTrace("psModules.nonlin",6,"NLMN: %f %d %f %f\n",flux,bin,correction_fluxes->data.F32[0],correction_fluxes->data.F32[bin]);
     371    if (flux < correction_fluxes->data.F32[0]) {
     372        return(0.0);
     373    }
     374/*     if (flux > correction_fluxes->data.F32[bin]) { */
     375/*      return(0.0); */
     376/*     } */
     377
     378    for (int i = 0; i < correction_fluxes->n - 1; i++) {
     379      psTrace("psModules.nonlin",6,"NLMN: %f %d %f %f %f %f\n",flux,i,correction_fluxes->data.F32[i],correction_fluxes->data.F32[i],
     380              correction_factors->data.F32[i],correction_factors->data.F32[i+1]);
     381        if ((flux >= correction_fluxes->data.F32[i])&&
     382            (flux <  correction_fluxes->data.F32[i+1])) {
     383            result = correction_factors->data.F32[i] +
     384                (flux - correction_fluxes->data.F32[i]) *
     385                ((correction_factors->data.F32[i+1] - correction_factors->data.F32[i]) /
     386                 (correction_fluxes->data.F32[i+1] - correction_fluxes->data.F32[i]));
     387            continue;
     388        }
     389    }
     390
     391/*   PS_BIN_FOR_VALUE(bin,correction_fluxes,flux); */
     392/*   if ((bin < 0)||(bin > correction_fluxes->n)) { */
     393/*     return(1.0); */
     394/*   } */
     395 
     396/*   PS_BIN_INTERPOLATE(result,correction_fluxes,correction_factors,bin,flux); */
     397    if (!isfinite(result)) {
     398        result = 0.0;
     399    }
     400/*     if (result <= 0) { */
     401/*      result = 1.0; */
     402/*     } */
     403    return(result);
     404}
     405
     406 
     407 
Note: See TracChangeset for help on using the changeset viewer.