IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42372


Ignore:
Timestamp:
Feb 4, 2023, 12:15:28 PM (3 years ago)
Author:
eugene
Message:

merge changes from trunk: new nonlinearity, allow detections under CTE masks

Location:
branches/eam_branches/ipp-20220316/ppImage
Files:
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20220316/ppImage

  • branches/eam_branches/ipp-20220316/ppImage/src/Makefile.am

    r42185 r42372  
    2424        ppImageDetrendRecord.c \
    2525        ppImageDetrendNonLinear.c \
     26        ppImageDetrendNewNonLinear.c \
    2627        ppImageDetrendFringe.c \
    2728        ppImageDetrendFree.c \
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImage.h

    r42167 r42372  
    3535    bool doAuxMask;                     // apply auxillary mask
    3636    bool doNonLin;                      // Non-linearity correction
     37    bool doNewNonLin;                   // Non-linearity correction
    3738    bool doOverscan;                    // Overscan subtraction
    3839    bool doNoiseMap;                    // Bias subtraction
     
    157158ppImageOptions *ppImageParseCamera(pmConfig *config);
    158159bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options);
     160bool ppImageMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     161                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     162                               psMetadata *source  // Source of mask bits
     163  );
    159164
    160165// apply the cell flips to the input data before analysis
     
    171176
    172177bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
     178
     179bool ppImageDetrendNewNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
    173180
    174181bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageArguments.c

    r42167 r42372  
    2525    fprintf(stderr, "\t-fringe/-fringelist: Fringe image and data.\n");
    2626    fprintf(stderr, "\t-linearity/-linearlist: linearity correction file.\n");
     27    fprintf(stderr, "\t-newnonlin/-newnonlinlist: non-linearity correction file (v 2023.01).\n");
    2728    fprintf(stderr, "\n");
    2829    exit (2);
     
    116117    pmConfigFileSetsMD (config->arguments, &argc, argv, "FRINGE", "-fringe", "-fringelist");
    117118    pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist");
     119    pmConfigFileSetsMD (config->arguments, &argc, argv, "NEWNONLIN", "-newnonlin", "-newnonlinlist");
    118120    pmConfigFileSetsMD (config->arguments, &argc, argv, "PATTERN.ROW.AMP", "-pattern-row-amplitude", "-not-defined");
    119121    pmConfigFileSetsMD (config->arguments, &argc, argv, "PATTERN.DEAD.CELLS", "-pattern-dead-cells", "-not-defined");
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendFree.c

    r29833 r42372  
    1414    "PPIMAGE.SHUTTER",
    1515    "PPIMAGE.LINEARITY",
     16    "PPIMAGE.NEWNONLIN",
    1617    NULL
    1718};
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendNonLinear.c

    r29833 r42372  
    1 #ifdef HAVE_CONFIG_H
    2 #include <config.h>
    3 #endif
    4 
    51#include "ppImage.h"
    62
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendReadout.c

    r42167 r42372  
    149149      // psLogMsg ("ppImage", 6, "nonlinear correction: %f sec\n", psTimerMark ("detrend.readout"));
    150150    }
     151    // New Non-linearity correction (exclusive of the above)
     152    if (options->doNewNonLin) {
     153      if (!ppImageDetrendNewNonLinear(input, detview, config)) {
     154        psError(PS_ERR_UNKNOWN, false, "Unable to correct Non-Linearity with new version (2023)");
     155        psFree(detview);
     156        return(false);
     157      }
     158      // psLogMsg ("ppImage", 6, "nonlinear correction: %f sec\n", psTimerMark ("detrend.readout"));
     159    }
    151160
    152161    // set up the dark and bias
     
    213222            psImageUnbin (noiseImage, noiseMap->image, binning);
    214223            psFree (binning);
    215             // Stolen from pmSkySubtract.c
    216             // CZW: Unneeded, as psImageUnbin does the bilinear interpolation?  It still looks blocky.
    217 /*          psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, RECIPE_NAME); // Recipe */
    218 /*          psAssert(recipe, "Should be there!"); */
    219 
    220 /*          psS32 xBinFactor = psMetadataLookupS32(NULL,recipe,"NOISE.XBIN"); */
    221 /*          psS32 yBinFactor = psMetadataLookupS32(NULL,recipe,"NOISE.YBIN"); */
    222 /*          psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BILINEAR, */
    223 /*                                                                             noiseMap->image, */
    224 /*                                                                             NULL, NULL, */
    225 /*                                                                             0, 0.0, 0.0, 0, 0, 0.0); */
    226 /*          for (psS32 row = 0; row < input->image->numRows; row++) { */
    227 /*            for (psS32 col = 0; col < input->image->numCols; col++) { */
    228 /*              // We calculate the F32 value of the pixel coordinates in the */
    229 /*              // binned image and then use a pixel interpolation routine to */
    230 /*              // determine the value of the pixel at that location. */
    231 /*              psF32 binRowF64 = ((psF32) row) / ((psF32) yBinFactor); */
    232 /*              psF32 binColF64 = ((psF32) col) / ((psF32) xBinFactor); */
    233 /*              // We add 0.5 to the pixel locations since the pixel */
    234 /*              // interpolation routine defines the location of pixel */
    235 /*              // (i, j) as (i+0.5, j+0.5). */
    236 /*              binRowF64+= 0.5; */
    237 /*              binColF64+= 0.5; */
    238 
    239 /*              double binPixel; */
    240 /*              if (!psImagePixelInterpolate(&binPixel, NULL, NULL, binColF64, binRowF64, interp)) { */
    241 /*                psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); */
    242 /*                psFree(interp); */
    243 /*                psFree(noiseImage); */
    244 /*                return NULL; */
    245 /*              } */
    246 /*              noiseImage->data.F32[row][col] = binPixel; */
    247 /*            } */
    248 /*          } */
    249 /*          psFree(interp); */
    250224        }
    251225
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendRecord.c

    r35612 r42372  
    7575    detrendRecord(options->doFringe,   detrend, config, view, "PPIMAGE.FRINGE",   "DETREND.FRINGE",   "Fringe filename");
    7676
    77     detrendRecord(options->doNonLin,   detrend, config, view, "PPIMAGE.LINEARITY","DETREND.NONLIN",   "Non-linearity table filename");
     77    detrendRecord(options->doNonLin,    detrend, config, view, "PPIMAGE.LINEARITY","DETREND.NONLIN",   "Non-linearity table filename");
     78    detrendRecord(options->doNewNonLin, detrend, config, view, "PPIMAGE.NEWNONLIN","DETREND.NEWNONLIN","Non-linearity table filename (v2023)");
    7879
    7980    detrendRecord(options->doDark & options->useVideoDark, detrend, config, view, "PPIMAGE.VIDEODARK", "DETREND.VIDEODARK", "VideoDark filename");
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageOptions.c

    r42167 r42372  
    2828    options->doAuxMask       = false;   // apply auxillary mask
    2929    options->doNonLin        = false;   // Non-linearity correction
     30    options->doNewNonLin     = false;   // New Non-linearity correction (v2023)
    3031    options->doOverscan      = false;   // Overscan subtraction
    3132    options->doNoiseMap      = false;   // Apply Read Noise Map
     
    175176    // XXX PAP: The overscan stuff needs to be updated following the reworked API
    176177
     178    // New Non-linearity (v 2023) recipe options
     179    // non-linearity corrections are loaded from a file defined in the detrend system or on the command-line
     180    if (psMetadataLookupBool(NULL, recipe, "NEWNONLIN")) {
     181        options->doNewNonLin = true;
     182    }
     183
     184    // XXX PAP: The overscan stuff needs to be updated following the reworked API
     185
    177186    // Overscan recipe options
    178187    // XXX EAM : we should abort on invalid options. default options?
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageParseCamera.c

    r42167 r42372  
    104104
    105105    if (options->doNonLin) {
    106       if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.LINEARITY", "LINEARITY",
    107                              PM_FPA_FILE_LINEARITY, PM_DETREND_TYPE_LINEARITY)) {
    108         psError(PS_ERR_IO, false, "Can't find a non-linearity correction source");
    109         psFree(options);
    110         return NULL;
    111       }
     106        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.LINEARITY", "LINEARITY",
     107                               PM_FPA_FILE_LINEARITY, PM_DETREND_TYPE_LINEARITY)) {
     108            psError(PS_ERR_IO, false, "Can't find a non-linearity correction source");
     109            psFree(options);
     110            return NULL;
     111        }
     112    }
     113    if (options->doNewNonLin) {
     114        // if the file has been specified on the command-line (-newnonlin file), then the file
     115        // is identified by the NEWNONLIN entry in config->arguments.  otherwise, load from the
     116        // detrend system as type NEWNONLIN
     117        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.NEWNONLIN", "NEWNONLIN",
     118                               PM_FPA_FILE_NEWNONLIN, PM_DETREND_TYPE_NEWNONLIN)) {
     119            psError(PS_ERR_IO, false, "Can't find a new non-linearity correction source");
     120            psFree(options);
     121            return NULL;
     122        }
    112123    }
    113124
  • branches/eam_branches/ipp-20220316/ppImage/src/ppImageSetMaskBits.c

    r42148 r42372  
    55#include "ppImage.h"
    66
     7// Structure to hold the properties of a mask value
     8typedef struct {
     9    char *badMaskName;                  // name for "bad" (i.e., mask me please) pixels
     10    char *fallbackName;                 // Fallback name in case a bad mask name is not defined
     11    psImageMaskType defaultMaskValue;   // Default value in case a bad mask name and its fallback are not defined
     12    bool isBad; // include this value as part of the MASK.VALUE entry (generically bad)
     13} pmConfigMaskInfo;
     14
     15static pmConfigMaskInfo ppimagemasks[] = {
     16    // Features of the detector
     17    { "DETECTOR",  NULL,       0x01, true }, // Something is wrong with the detector
     18    { "FLAT",      "DETECTOR", 0x01, true }, // Pixel doesn't flat-field properly
     19    { "DARK",      "DETECTOR", 0x01, true }, // Pixel doesn't dark-subtract properly
     20    { "BLANK",     "DETECTOR", 0x01, true }, // Pixel doesn't contain valid data
     21    { "CTE",       "DETECTOR", 0x01, false }, // Pixel has poor CTE
     22    { "BURNTOOL",  NULL,       0x04, false }, // Pixel has been touched by burntool
     23    // Invalid signal ranges
     24    { "SAT",       NULL,       0x02, true  }, // Pixel is saturated or non-linear
     25    { "LOW",       "SAT",      0x02, true  }, // Pixel is low
     26    { "SUSPECT",   NULL,       0x04, false }, // Pixel is suspected of being bad
     27    // Non-astronomical structures
     28    { "CR",        NULL,       0x08, true  }, // Pixel contains a cosmic ray
     29    { "SPIKE",     NULL,       0x08, false  }, // Pixel contains a diffraction spike
     30    { "GHOST",     NULL,       0x08, false  }, // Pixel contains an optical ghost
     31    { "STREAK",    NULL,       0x08, false  }, // Pixel contains a streak
     32    { "CROSSTALK", NULL,       0x08, false  }, // Pixel contains crosstalk data
     33    { "STARCORE",  NULL,       0x08, false  }, // Pixel contains a bright star core
     34    // Effects of convolution and interpolation
     35    { "CONV.BAD",  NULL,       0x02, true  }, // Pixel is bad after convolution with a bad pixel
     36    { "CONV.POOR", NULL,       0x04, false }, // Pixel is poor after convolution with a bad pixel
     37};
     38
    739bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options) {
    840
    9     if (!pmConfigMaskSetBits(&options->maskValue, &options->markValue, config)) {
    10         psError (PS_ERR_UNKNOWN, true, "Unable to define the mask bit values");
    11         return false;
     41
     42    // Look up recipe values
     43    psMetadata *pprecipe = psMetadataLookupMetadata(NULL, config->recipes, RECIPE_NAME);
     44
     45    psAssert(pprecipe, "We checked this earlier, so it should be here.");
     46    bool doDetectCTE = psMetadataLookupBool(NULL, pprecipe, "DETECT.CTE"); // Do detections on pixels underneath CTE masks
     47
     48    // this function sets the required single-image mask bits
     49    if(!doDetectCTE) {
     50      if (!pmConfigMaskSetBits (&options->maskValue, &options->markValue, config)) {
     51          psError (PS_ERR_UNKNOWN, true, "Unable to define the mask bit values");
     52          return false;
     53      }
     54    } else {
     55      psMetadata *maskrecipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
     56      if (!maskrecipe) {
     57          psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
     58          return false;
     59      }
     60      if (!ppImageMaskSetInMetadata(&options->maskValue, &options->markValue, maskrecipe)) {
     61          psError (PS_ERR_UNKNOWN, true, "Unable to determine the mask value");
     62          return false;
     63      }
    1264    }
    1365
     
    66118    return true;
    67119}
     120
     121
     122bool ppImageMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     123                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     124                               psMetadata *source  // Source of mask bits
     125    )
     126{
     127    PS_ASSERT_METADATA_NON_NULL(source, false);
     128
     129    // Ensure all the bad mask names exist, and set the value to catch all bad pixels
     130    psImageMaskType maskValue = 0;           // Value to mask to catch all the bad pixels
     131    psImageMaskType allMasks = 0;            // Value to mask to catch all masked bits (to set MARK)
     132
     133    int nMasks = sizeof (ppimagemasks) / sizeof (pmConfigMaskInfo);
     134
     135    for (int i = 0; i < nMasks; i++) {
     136        bool mdok;                      // Status of MD lookup
     137        psImageMaskType value = psMetadataLookupImageMaskFromGeneric(&mdok, source, ppimagemasks[i].badMaskName); // Value of mask
     138        if (!mdok) {
     139            psWarning ("problem with mask value %s\n", ppimagemasks[i].badMaskName);
     140        }
     141
     142        if (!value) {
     143            if (ppimagemasks[i].fallbackName) {
     144                value = psMetadataLookupImageMaskFromGeneric(&mdok, source, ppimagemasks[i].fallbackName);
     145            }
     146            if (!value) {
     147                value = ppimagemasks[i].defaultMaskValue;
     148            }
     149            psMetadataAddImageMask(source, PS_LIST_TAIL, ppimagemasks[i].badMaskName, PS_META_REPLACE, NULL, value);
     150        }
     151        if (ppimagemasks[i].isBad) {
     152            maskValue |= value;
     153        }
     154        allMasks |= value;
     155    }
     156
     157    // search for an unset bit to use for MARK:
     158    psImageMaskType markValue = 0x00;
     159    psImageMaskType markTrial = 0x01;
     160
     161    int nBits = sizeof(psImageMaskType) * 8;
     162    for (int i = 0; !markValue && (i < nBits); i++) {
     163        if (allMasks & markTrial) {
     164            markTrial <<= 1;
     165        } else {
     166            markValue = markTrial;
     167        }
     168    }
     169    if (!markValue) {
     170        psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!");
     171        return false;
     172    }
     173
     174    // update the list with the results
     175    psMetadataAddImageMask(source, PS_LIST_TAIL, "MASK.VALUE", PS_META_REPLACE, NULL, maskValue);
     176    psMetadataAddImageMask(source, PS_LIST_TAIL, "MARK.VALUE", PS_META_REPLACE, NULL, markValue);
     177
     178    if (outMaskValue) {
     179        *outMaskValue = maskValue;
     180    }
     181    if (outMarkValue) {
     182        *outMarkValue = markValue;
     183    }
     184
     185    return true;
     186}
     187
Note: See TracChangeset for help on using the changeset viewer.