IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

added procedure to remove pixel NaNing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.