IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42293 for trunk/ppImage/src


Ignore:
Timestamp:
Sep 27, 2022, 5:08:10 PM (4 years ago)
Author:
tdeboer
Message:

adding CTE detection functionality and new CTE source flag

Location:
trunk/ppImage/src
Files:
2 edited

Legend:

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

    r41894 r42293  
    156156ppImageOptions *ppImageParseCamera(pmConfig *config);
    157157bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options);
     158bool ppImageMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     159                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     160                               psMetadata *source  // Source of mask bits
     161  );
    158162
    159163// apply the cell flips to the input data before analysis
  • trunk/ppImage/src/ppImageSetMaskBits.c

    r37406 r42293  
    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
     
    63115    return true;
    64116}
     117
     118
     119bool ppImageMaskSetInMetadata(psImageMaskType *outMaskValue, // Value of MASK.VALUE, returned
     120                               psImageMaskType *outMarkValue, // Value of MARK.VALUE, returned
     121                               psMetadata *source  // Source of mask bits
     122    )
     123{
     124    PS_ASSERT_METADATA_NON_NULL(source, false);
     125
     126    // Ensure all the bad mask names exist, and set the value to catch all bad pixels
     127    psImageMaskType maskValue = 0;           // Value to mask to catch all the bad pixels
     128    psImageMaskType allMasks = 0;            // Value to mask to catch all masked bits (to set MARK)
     129
     130    int nMasks = sizeof (ppimagemasks) / sizeof (pmConfigMaskInfo);
     131
     132    for (int i = 0; i < nMasks; i++) {
     133        bool mdok;                      // Status of MD lookup
     134        psImageMaskType value = psMetadataLookupImageMaskFromGeneric(&mdok, source, ppimagemasks[i].badMaskName); // Value of mask
     135        if (!mdok) {
     136            psWarning ("problem with mask value %s\n", ppimagemasks[i].badMaskName);
     137        }
     138
     139        if (!value) {
     140            if (ppimagemasks[i].fallbackName) {
     141                value = psMetadataLookupImageMaskFromGeneric(&mdok, source, ppimagemasks[i].fallbackName);
     142            }
     143            if (!value) {
     144                value = ppimagemasks[i].defaultMaskValue;
     145            }
     146            psMetadataAddImageMask(source, PS_LIST_TAIL, ppimagemasks[i].badMaskName, PS_META_REPLACE, NULL, value);
     147        }
     148        if (ppimagemasks[i].isBad) {
     149            maskValue |= value;
     150        }
     151        allMasks |= value;
     152    }
     153
     154    // search for an unset bit to use for MARK:
     155    psImageMaskType markValue = 0x00;
     156    psImageMaskType markTrial = 0x01;
     157
     158    int nBits = sizeof(psImageMaskType) * 8;
     159    for (int i = 0; !markValue && (i < nBits); i++) {
     160        if (allMasks & markTrial) {
     161            markTrial <<= 1;
     162        } else {
     163            markValue = markTrial;
     164        }
     165    }
     166    if (!markValue) {
     167        psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!");
     168        return false;
     169    }
     170
     171    // update the list with the results
     172    psMetadataAddImageMask(source, PS_LIST_TAIL, "MASK.VALUE", PS_META_REPLACE, NULL, maskValue);
     173    psMetadataAddImageMask(source, PS_LIST_TAIL, "MARK.VALUE", PS_META_REPLACE, NULL, markValue);
     174
     175    if (outMaskValue) {
     176        *outMaskValue = maskValue;
     177    }
     178    if (outMarkValue) {
     179        *outMarkValue = markValue;
     180    }
     181
     182    return true;
     183}
     184
Note: See TracChangeset for help on using the changeset viewer.