IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 29833 for trunk


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:
29 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/dbconfig

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • trunk/ippScripts

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • trunk/ippTasks

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • trunk/ippTools

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • trunk/ippconfig/gpc1/ppImage.config

    r27407 r29833  
    262262  NOISEMAP METADATA
    263263  END   
     264  LINEARITY METADATA
     265  END
    264266END
    265267
  • trunk/ippconfig/recipes/filerules-mef.mdc

    r29379 r29833  
    6363PPIMAGE.FRINGE          INPUT    @DETDB        CHIP       FRINGE
    6464PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE     
     65PPIMAGE.LINEARITY       INPUT    @DETDB        CHIP       LINEARITY
    6566
    6667## Files used by ppMerge
  • trunk/ippconfig/recipes/filerules-simple.mdc

    r29554 r29833  
    2828PPIMAGE.FRINGE            INPUT    @DETDB        CHIP       FRINGE
    2929PPIMAGE.SHUTTER           INPUT    @DETDB        CHIP       IMAGE     
     30PPIMAGE.LINEARITY         INPUT    @DETDB        CHIP       LINEARITY
    3031                         
    3132## Files used by ppMerge 
  • trunk/ippconfig/recipes/filerules-split.mdc

    r29780 r29833  
    4646PPIMAGE.FRINGE            INPUT    @DETDB        CHIP       FRINGE
    4747PPIMAGE.SHUTTER           INPUT    @DETDB        CHIP       IMAGE
     48PPIMAGE.LINEARITY         INPUT    @DETDB        CHIP       LINEARITY
    4849
    4950## Files used by ppMerge
  • trunk/ppImage/src/ppImage.h

    r28043 r29833  
    155155bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
    156156
    157 bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options);
     157//bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options);
     158bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
    158159bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
    159160bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
  • trunk/ppImage/src/ppImageArguments.c

    r24485 r29833  
    2424    fprintf(stderr, "\t-mask/-masklist: Mask image.\n");
    2525    fprintf(stderr, "\t-fringe/-fringelist: Fringe image and data.\n");
     26    fprintf(stderr, "\t-linearity/-linearlist: linearity correction file.\n");
    2627    fprintf(stderr, "\n");
    2728    exit (2);
     
    120121    pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask", "-masklist");
    121122    pmConfigFileSetsMD (config->arguments, &argc, argv, "FRINGE", "-fringe", "-fringelist");
     123    pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist");
    122124
    123125    // chip selection is used to limit chips to be processed
  • trunk/ppImage/src/ppImageDefineFile.c

    r26494 r29833  
    1515        file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
    1616        if (!status) {
    17             psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     17            psError(PS_ERR_UNKNOWN, false, "failed to load file definition ARG LIST");
    1818            return false;
    1919        }
     
    2323        file = pmFPAfileDefineFromRun(&status, NULL, config, filerule);
    2424        if (!status) {
    25             psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     25            psError(PS_ERR_UNKNOWN, false, "failed to load file definition RUN");
    2626            return false;
    2727        }
     
    3131        file = pmFPAfileDefineFromConf(&status, config, filerule);
    3232        if (!status) {
    33             psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     33            psError(PS_ERR_UNKNOWN, false, "failed to load file definition CONFIG");
    3434            return false;
    3535        }
     
    3939        file = pmFPAfileDefineFromDetDB(&status, config, filerule, input, detrendType);
    4040        if (!status) {
    41             psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     41            psError(PS_ERR_UNKNOWN, false, "failed to load file definition DETREND");
    4242            return false;
    4343        }
  • trunk/ppImage/src/ppImageDetrendFree.c

    r24485 r29833  
    1313    "PPIMAGE.FLAT",
    1414    "PPIMAGE.SHUTTER",
     15    "PPIMAGE.LINEARITY",
    1516    NULL
    1617};
     
    2324
    2425        pmFPAfile *file = psMetadataLookupPtr(&status, config->files, detrendTypes[i]); // File of interest
     26        psTrace("pmFPAfileFree",1,"Working on %s\n",detrendTypes[i]);
    2527        if (!file) continue; // not all detrends are used in any given run
    2628
  • trunk/ppImage/src/ppImageDetrendNonLinear.c

    r11702 r29833  
    4444}
    4545
    46 bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options) {
     46
     47bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *detview, pmConfig  *config) {
     48    bool status;
     49
     50    pmFPAfile *linearity_file = psMetadataLookupPtr(&status,config->files,"PPIMAGE.LINEARITY");
     51    psFits *linearity_fits = linearity_file->fits;
     52
     53    char *extname = psMetadataLookupStr(&status,input->parent->concepts,"CELL.NAME");
     54    if (!extname) {
     55        psError(PS_ERR_IO, false, "missing CELL.NAME in concepts");
     56        return(false);
     57    }
     58
     59    if (!psFitsMoveExtName(linearity_fits,extname)) {
     60        psError(PS_ERR_IO, false, "Unable to move to non-linearity table %s", extname);
     61        return(false);
     62    }
     63 
     64    psArray *table = psFitsReadTable(linearity_fits);
     65    if (!table) {
     66        psError(PS_ERR_IO, false, "Unable to read non-linearity table.\n");
     67        return(false);
     68    }
     69
     70    // It might be better to pack lookup table here...
     71    // Why? I only use that lookup table once for the single cell it matches.
     72 
     73    if (!pmNonLinearityApply(input,table)) {
     74        psError(PS_ERR_UNKNOWN, false, "Unable to apply non-linearity corrections.\n");
     75        psFree (table);
     76        return(false);
     77    }       
     78    psFree (table);
     79
     80    return true;
     81}
     82
     83bool ppImageDetrendNonLinear_Original(pmReadout *input, ppImageOptions *options) {
    4784
    4885    psMetadataItem *concept;
     
    5996
    6097      case PS_DATA_METADATA:
    61         // XXX EAM: this is somewhat confusing : let's wrap in a function when i understand it
    62 
    6398        // Go looking for the value in the hierarchy
    6499        concept = psMetadataLookup(cell->concepts, options->nonLinearSource);
  • trunk/ppImage/src/ppImageDetrendReadout.c

    r26653 r29833  
    5151    }
    5252
    53 
    54 # if 0
     53    // Subtract the overscan
     54    if (options->doOverscan) {
     55      if (!pmOverscanSubtract (input, options->overscan)) {
     56        psError(PS_ERR_UNKNOWN, false, "Unable to subtract overscan.");
     57        psFree(detview);
     58        return false;
     59      }
     60    }
     61
    5562    // Non-linearity correction
    5663    if (options->doNonLin) {
    57         ppImageDetrendNonLinear(detrend->input, input, options);
    58     }
    59 # endif
     64      //      linearity = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.LINEARITY");
     65      if (!ppImageDetrendNonLinear(input,detview,config)) {
     66        psError(PS_ERR_UNKNOWN, false, "Unable to correct NonLinearity");
     67        psFree(detview);
     68        return(false);
     69      }
     70      /*       ppImageDetrendNonLinear(detrend->input, input, options); */
     71    }
    6072
    6173    // set up the dark and bias
     
    7789    }
    7890
    79     // Bias, dark and overscan subtraction are all merged.
    80     if (options->doBias || options->doOverscan) {
    81         if (!pmBiasSubtract(input, options->overscan, bias, oldDark, view)) {
     91    // Bias and temperature-independent-dark subtraction are merged.
     92    if (options->doBias) {
     93        if (!pmBiasSubtract(input, bias, oldDark, view)) {
    8294            psError(PS_ERR_UNKNOWN, false, "Unable to subtract bias.");
    8395            psFree(detview);
     
    8597        }
    8698    }
    87 
     99   
    88100    // Weight on the basis of pixel value needs to be done after the overscan has been subtracted
    89101    if (options->doVarianceBuild) {
  • trunk/ppImage/src/ppImageLoop.c

    r28375 r29833  
    152152            ESCAPE("Unable to free detrend images");
    153153        }
    154 
     154   
    155155        // Apply the fringe correction
    156156        if (options->doFringe) {
  • trunk/ppImage/src/ppImageOptions.c

    r28043 r29833  
    88{
    99    psFree(options->overscan);
    10     psFree(options->nonLinearData);
    11     psFree(options->nonLinearSource);
     10    // psFree(options->nonLinearData);
     11    // psFree(options->nonLinearSource);
    1212}
    1313
     
    130130        psMetadataItem *dataItem = psMetadataLookup(recipe, "NONLIN.DATA");
    131131        if (! dataItem) {
    132             psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but unable to "
    133                      "find NONLIN.DATA in recipe %s.", RECIPE_NAME);
     132            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.DATA in recipe %s.", RECIPE_NAME);
    134133            exit(EXIT_FAILURE);
    135134        }
     
    147146            // This is a menu; we need the key
    148147          case PS_DATA_METADATA:
    149             {
    150                 bool status;
    151                 options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
    152                 if (! status || ! options->nonLinearSource) {
    153                     psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but unable to "
    154                             "find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
    155                     exit(EXIT_FAILURE);
    156                 }
    157             }
     148            options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
     149            if (! status || ! options->nonLinearSource) {
     150                psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
     151                exit(EXIT_FAILURE);
     152            }
    158153            break;
    159154          default:
    160             psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but "
    161                     "NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
     155            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
    162156            exit(EXIT_FAILURE);
    163157        }
  • trunk/ppImage/src/ppImageParseCamera.c

    r26895 r29833  
    7373            return NULL;
    7474        }
     75    }
     76
     77    if (options->doNonLin) {
     78      if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.LINEARITY", "LINEARITY",
     79                             PM_FPA_FILE_LINEARITY, PM_DETREND_TYPE_LINEARITY)) {
     80        psError(PS_ERR_IO, false, "Can't find a non-linearity correction source");
     81        psFree(options);
     82        return NULL;
     83      }
    7584    }
    7685
  • trunk/psLib/src/types/psMetadata.c

    r27646 r29833  
    109109    type = metadataItem->type;
    110110
    111 
     111    //    fprintf(stderr,"%s %s %d\n",metadataItem->name,metadataItem->comment,type);
    112112    psMemDecrRefCounter(metadataItem->name);
    113113    psMemDecrRefCounter(metadataItem->comment);
  • trunk/psModules/src/camera/pmFPAfile.c

    r27657 r29833  
    3636        return;
    3737    }
    38 
     38    psTrace ("pmFPAfileFree", 5, "freeing %s %ld\n", file->name,(psU64) file->fits);
    3939    psAssert(!fpaFileFreeStrict || file->fits == NULL, "File %s wasn't closed.", file->name);
    4040
     
    523523    if (!strcasecmp(type, "HEADER"))     {
    524524        return PM_FPA_FILE_HEADER;
     525    }
     526    if (!strcasecmp(type, "LINEARITY"))  {
     527      return PM_FPA_FILE_LINEARITY;
    525528    }
    526529    // deprecate this?
  • trunk/psModules/src/camera/pmFPAfile.h

    r27657 r29833  
    5050    PM_FPA_FILE_SRCTEXT,
    5151    PM_FPA_FILE_PATTERN,
     52    PM_FPA_FILE_LINEARITY,
    5253} pmFPAfileType;
    5354
  • trunk/psModules/src/camera/pmFPAfileFitsIO.c

    r27989 r29833  
    145145      case PM_FPA_FILE_FRINGE:
    146146      case PM_FPA_FILE_DARK:
     147      case PM_FPA_FILE_LINEARITY:
    147148      case PM_FPA_FILE_CMP:
    148149      case PM_FPA_FILE_CMF:
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r29004 r29833  
    233233      case PM_FPA_FILE_JPEG:
    234234      case PM_FPA_FILE_KAPA:
     235      case PM_FPA_FILE_LINEARITY:
    235236        break;
    236237      default:
     
    560561      case PM_FPA_FILE_ASTROM_MODEL:
    561562      case PM_FPA_FILE_ASTROM_REFSTARS:
     563      case PM_FPA_FILE_LINEARITY:
    562564        psTrace ("psModules.camera", 5, "closing %s (%s) (%d:%d:%d)\n", file->filename, file->name, view->chip, view->cell, view->readout);
    563565        status = psFitsClose (file->fits);
     
    575577      case PM_FPA_FILE_JPEG:
    576578      case PM_FPA_FILE_KAPA:
     579
    577580        break;
    578581
     
    619622      case PM_FPA_FILE_FRINGE:
    620623      case PM_FPA_FILE_DARK:
     624        //
    621625        status = pmFPAviewFreeData(view, file);
    622626        break;
     
    636640      case PM_FPA_FILE_JPEG:
    637641      case PM_FPA_FILE_KAPA:
     642      case PM_FPA_FILE_LINEARITY:
    638643        psTrace ("psModules.camera", 5, "nothing to free for %s (%s)\n", file->filename, file->name);
    639644        return true;
     
    791796      case PM_FPA_FILE_ASTROM_MODEL:
    792797      case PM_FPA_FILE_ASTROM_REFSTARS:
     798      case PM_FPA_FILE_LINEARITY:
    793799        psTrace ("psModules.camera", 5, "opening %s (%s) (%d:%d:%d)\n",
    794800                 file->filename, file->name, view->chip, view->cell, view->readout);
  • trunk/psModules/src/detrend/pmBias.c

    r28405 r29833  
    163163}
    164164
    165 bool pmBiasSubtract(pmReadout *in, pmOverscanOptions *overscanOpts,
     165bool pmBiasSubtract(pmReadout *in,
    166166                    pmReadout *bias, pmReadout *dark, const pmFPAview *view)
    167167{
     
    184184
    185185    pmHDU *hdu = pmHDUFromReadout(in);  // HDU of interest
    186 
    187     if (!pmOverscanSubtract (in, overscanOpts)) {
    188         return false;
    189     }
    190186
    191187    // Bias frame subtraction
     
    247243    psString timeString = psTimeToISO(time); // String with time
    248244    psFree(time);
    249     psStringPrepend(&timeString, "Overscan/bias/dark processing completed at ");
     245    psStringPrepend(&timeString, "Bias/dark processing completed at ");
    250246    psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK,
    251247                     timeString, "");
  • trunk/psModules/src/detrend/pmBias.h

    r19432 r29833  
    2121/// bias (if non-NULL) and dark (if non-NULL) scaled by the CELL.DARKTIME concept.
    2222bool pmBiasSubtract(pmReadout *in,      ///< Input readout, to be overscan/bias/dark corrected
    23                     pmOverscanOptions *overscanOpts, ///< Options for overscan subtraction, or NULL
    2423                    pmReadout *bias, ///< Bias to subtract, or NULL
    2524                    pmReadout *dark, ///< Dark to scale and subtract, or NULL
  • trunk/psModules/src/detrend/pmDetrendDB.c

    r24490 r29833  
    106106        DETREND_STRING_CASE(ASTROM);
    107107        DETREND_STRING_CASE(NOISEMAP);
     108        DETREND_STRING_CASE(LINEARITY);
    108109    default:
    109110        return NULL;
  • trunk/psModules/src/detrend/pmDetrendDB.h

    r24490 r29833  
    3636    PM_DETREND_TYPE_ASTROM,
    3737    PM_DETREND_TYPE_NOISEMAP,
     38    PM_DETREND_TYPE_LINEARITY,
    3839} pmDetrendType;
    3940
  • 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 
  • trunk/psModules/src/detrend/pmNonLinear.h

    r12696 r29833  
    3131                                const psVector *outFlux ///< Table column with output fluxes
    3232                               );
    33 
     33bool pmNonLinearityApply(pmReadout *inputReadout, psArray *Ltab);
     34psF32 pmNonLinearityMeasure(psF32 flux, psVector *correction_fluxes, psVector *correction_factors);
    3435/// @}
    3536#endif
Note: See TracChangeset for help on using the changeset viewer.