IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41382 for trunk/ppSub/src


Ignore:
Timestamp:
Jun 23, 2020, 3:29:09 PM (6 years ago)
Author:
tdeboer
Message:

added procedure to remove pixel NaNing

Location:
trunk/ppSub/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppSub/src/ppSub.h

    r31156 r41382  
    190190void ppSubSetThreads (void);
    191191
     192// ppSubMaskSetInMetadata examines named mask values and set the bits for maskValue and
     193// markValue.  Ensures that the below-named mask values are set, and calculates the mask value
     194// to catch all of the mask values marked as 'bad'.  Supplies the fallback name if the primary
     195// name is not found, or the default values if the fallback name is not found.
     196bool ppSubMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     197                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     198                               psMetadata *source  // Source of mask bits
     199  );
     200
     201// lookup an image mask value by name from a psMetadata, without requiring the entry to
     202// be of type psImageMaskType, but verifying that it will fit in psImageMaskType
     203psImageMaskType psMetadataLookupImageMaskFromGeneric (bool *status, const psMetadata *md, const char *name);
     204
    192205///@}
    193206#endif
  • trunk/ppSub/src/ppSubBackground.c

    r29937 r41382  
    3333    psAssert(psphotRecipe, "Need PSPHOT recipe for binning");
    3434
     35    bool doApplyMaskNaN = psMetadataLookupBool(&mdok, ppSubRecipe, "APPLY.PIXELNAN"); // NaN the pixels underneath masks
     36
    3537    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask
    3638
     
    6466        for (int x = 0; x < numCols; x++) {
    6567            // special case 1: NAN the masked pixels
    66             if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskBad) {
     68            if(doApplyMaskNaN) {
     69              if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskBad) {
    6770                image->data.F32[y][x] = NAN;
    6871                continue;
    69             }
    70             // special case 1: NAN & mask pixels without a valid background model
     72              }
     73            }
     74            // special case 2: NAN & mask pixels without a valid background model
    7175            float value = psImageUnbinPixel(x + 0.5, y + 0.5, modelImage, binning); // Background value
    7276            if (!isfinite(value)) {
  • trunk/ppSub/src/ppSubReadoutSubtract.c

    r31435 r41382  
    3333    bool noConvolve = psMetadataLookupBool(&mdok, recipe, "NOCONVOLVE"); // Do not use convolved images.
    3434    bool addPair = psMetadataLookupBool(&mdok, recipe, "ADD.NOT.SUBTRACT"); // add instead of subtracting
     35    bool doApplyMaskNaN = psMetadataLookupBool(&mdok, recipe, "APPLY.PIXELNAN"); // NaN the pixels underneath masks
    3536
    3637    pmFPAview *view = ppSubViewReadout(); // View to readout
     
    7374    // NAN the masked pixels in the diff image (pixels masked in A are not yet NAN'ed in B)
    7475    psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config) | pmConfigMaskGet("BLANK", config); // Bits to mask in inputs
    75     for (int iy = 0; iy < outRO->image->numRows; iy++) {
     76    if(doApplyMaskNaN) {
     77      for (int iy = 0; iy < outRO->image->numRows; iy++) {
    7678        for (int ix = 0; ix < outRO->image->numCols; ix++) {
    7779            if ((outRO->mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal) == 0) continue;
    7880            outRO->image->data.F32[iy][ix] = NAN;
    7981        }
     82      }
    8083    }
    8184
  • trunk/ppSub/src/ppSubSetMasks.c

    r30619 r41382  
    2222#include "ppSub.h"
    2323
     24// Structure to hold the properties of a mask value
     25typedef struct {
     26    char *badMaskName;                  // name for "bad" (i.e., mask me please) pixels
     27    char *fallbackName;                 // Fallback name in case a bad mask name is not defined
     28    psImageMaskType defaultMaskValue;   // Default value in case a bad mask name and its fallback are not defined
     29    bool isBad; // include this value as part of the MASK.VALUE entry (generically bad)
     30} pmConfigMaskInfo;
     31
     32static pmConfigMaskInfo skycellmasks[] = {
     33    // Features of the detector
     34    { "DETECTOR",  NULL,       0x01, false }, // Something is wrong with the detector
     35    { "FLAT",      "DETECTOR", 0x01, false }, // Pixel doesn't flat-field properly
     36    { "DARK",      "DETECTOR", 0x01, false }, // Pixel doesn't dark-subtract properly
     37    { "BLANK",     "DETECTOR", 0x01, true }, // Pixel doesn't contain valid data
     38    { "CTE",       "DETECTOR", 0x01, false }, // Pixel has poor CTE
     39    { "BURNTOOL",  NULL,       0x04, false }, // Pixel has been touched by burntool
     40    // Invalid signal ranges
     41    { "SAT",       NULL,       0x02, true  }, // Pixel is saturated or non-linear
     42    { "LOW",       "SAT",      0x02, true  }, // Pixel is low
     43    { "SUSPECT",   NULL,       0x04, false }, // Pixel is suspected of being bad
     44    // Non-astronomical structures
     45    { "CR",        NULL,       0x08, true  }, // Pixel contains a cosmic ray
     46    { "SPIKE",     NULL,       0x08, false  }, // Pixel contains a diffraction spike
     47    { "GHOST",     NULL,       0x08, false  }, // Pixel contains an optical ghost
     48    { "STREAK",    NULL,       0x08, false  }, // Pixel contains streak data
     49    { "STARCORE",  NULL,       0x08, false  }, // Pixel contains a bright star core
     50    // Effects of convolution and interpolation
     51    { "CONV.BAD",  NULL,       0x02, true  }, // Pixel is bad after convolution with a bad pixel
     52    { "CONV.POOR", NULL,       0x04, false }, // Pixel is poor after convolution with a bad pixel
     53};
     54
    2455bool ppSubSetMasks(pmConfig *config)
    2556{
    2657    psAssert(config, "Require configuration");
    2758
    28     psImageMaskType maskValue, markValue; // Mask values
    29     if (!pmConfigMaskSetBits(&maskValue, &markValue, config)) {
    30         psError(PPSUB_ERR_CONFIG, false, "Unable to determine mask value.");
    31         return false;
    32     }
    33 
    34     // Set the mask bits needed by psphot (in psphot recipe)
    35     psphotSetMaskRecipe(config, maskValue, markValue);
    36 
    3759    // Look up recipe values
    3860    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
    3961    psAssert(recipe, "We checked this earlier, so it should be here.");
     62    bool doApplyMaskNaN = psMetadataLookupBool(NULL, recipe, "APPLY.PIXELNAN"); // NaN the pixels underneath masks
     63
     64    psImageMaskType maskValue, markValue; // Mask values
     65    if(doApplyMaskNaN) {
     66      if (!pmConfigMaskSetBits(&maskValue, &markValue, config)) {
     67          psError(PPSUB_ERR_CONFIG, false, "Unable to determine mask value.");
     68          return false;
     69      }
     70    } else {
     71      psMetadata *maskrecipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
     72      if (!maskrecipe) {
     73          psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
     74          return false;
     75      }
     76      if (!ppSubMaskSetInMetadata(&maskValue, &markValue, maskrecipe)) {
     77          psError(PPSUB_ERR_CONFIG, false, "Unable to determine mask value.");
     78          return false;
     79      }
     80    }
     81
     82    // Set the mask bits needed by psphot (in psphot recipe)
     83    psphotSetMaskRecipe(config, maskValue, markValue);
     84
    4085
    4186    psImageMaskType satValue = pmConfigMaskGet("SAT", config);
     
    121166    return true;
    122167}
     168
     169bool ppSubMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     170                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     171                               psMetadata *source  // Source of mask bits
     172    )
     173{
     174    PS_ASSERT_METADATA_NON_NULL(source, false);
     175
     176    // Ensure all the bad mask names exist, and set the value to catch all bad pixels
     177    psImageMaskType maskValue = 0;           // Value to mask to catch all the bad pixels
     178    psImageMaskType allMasks = 0;            // Value to mask to catch all masked bits (to set MARK)
     179
     180    int nMasks = sizeof (skycellmasks) / sizeof (pmConfigMaskInfo);
     181
     182    for (int i = 0; i < nMasks; i++) {
     183        bool mdok;                      // Status of MD lookup
     184        psImageMaskType value = psMetadataLookupImageMaskFromGeneric(&mdok, source, skycellmasks[i].badMaskName); // Value of mask
     185        if (!mdok) {
     186            psWarning ("problem with mask value %s\n", skycellmasks[i].badMaskName);
     187        }
     188
     189        if (!value) {
     190            if (skycellmasks[i].fallbackName) {
     191                value = psMetadataLookupImageMaskFromGeneric(&mdok, source, skycellmasks[i].fallbackName);
     192            }
     193            if (!value) {
     194                value = skycellmasks[i].defaultMaskValue;
     195            }
     196            psMetadataAddImageMask(source, PS_LIST_TAIL, skycellmasks[i].badMaskName, PS_META_REPLACE, NULL, value);
     197        }
     198        if (skycellmasks[i].isBad) {
     199            maskValue |= value;
     200        }
     201        allMasks |= value;
     202    }
     203
     204    // search for an unset bit to use for MARK:
     205    psImageMaskType markValue = 0x00;
     206    psImageMaskType markTrial = 0x01;
     207
     208    int nBits = sizeof(psImageMaskType) * 8;
     209    for (int i = 0; !markValue && (i < nBits); i++) {
     210        if (allMasks & markTrial) {
     211            markTrial <<= 1;
     212        } else {
     213            markValue = markTrial;
     214        }
     215    }
     216    if (!markValue) {
     217        psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!");
     218        return false;
     219    }
     220
     221    // update the list with the results
     222    psMetadataAddImageMask(source, PS_LIST_TAIL, "MASK.VALUE", PS_META_REPLACE, NULL, maskValue);
     223    psMetadataAddImageMask(source, PS_LIST_TAIL, "MARK.VALUE", PS_META_REPLACE, NULL, markValue);
     224
     225    if (outMaskValue) {
     226        *outMaskValue = maskValue;
     227    }
     228    if (outMarkValue) {
     229        *outMarkValue = markValue;
     230    }
     231
     232    return true;
     233}
     234
Note: See TracChangeset for help on using the changeset viewer.