IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 15, 2008, 10:25:00 AM (18 years ago)
Author:
eugene
Message:

re-organization of the named mask bit handling: pmConfigMaskSetBits now assigns the bits to names and make the recipe consistent

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/config/pmConfigMask.c

    r16815 r18554  
    99#include "pmConfigMask.h"
    1010
    11 psMaskType pmConfigMask(const char *masks, const pmConfig *config)
     11psMaskType pmConfigMaskGet(const char *masks, const pmConfig *config)
    1212{
    1313    assert (config);
     
    3939    return mask;
    4040}
     41
     42bool pmConfigMaskSet(const pmConfig *config, const char *maskName, psMaskType maskValue)
     43{
     44    assert (config);
     45    PS_ASSERT_STRING_NON_EMPTY(maskName, false);
     46
     47    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
     48    if (!recipe) {
     49        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
     50        return false;
     51    }
     52
     53    psMetadataAddU8 (recipe, PS_LIST_TAIL, maskName, PS_META_REPLACE, "user-defined mask", maskValue);
     54
     55    return true;
     56}
     57
     58// replace the named masks in the recipe with values in the header:
     59// replace only the names in the header in the recipe
     60bool pmConfigMaskReadHeader (pmConfig *config, psMetadata *header) {
     61
     62    bool status = false;
     63    char namekey[80];
     64    char valuekey[80];
     65
     66    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
     67    if (!recipe) {
     68        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
     69        return false;
     70    }
     71
     72    int nMask = psMetadataLookupS32 (&status, header, "MSKNUM");
     73    if (!status) {
     74        psError(PS_ERR_UNKNOWN, true, "Unable to find MSKNUM in header.");
     75        return false;
     76    }
     77
     78    for (int i = 0; i < nMask; i++) {
     79
     80        snprintf (namekey,  64, "MSKNAM%02d", i);
     81        snprintf (valuekey, 64, "MSKVAL%02d", i);
     82
     83        char *name = psMetadataLookupStr (&status, header, namekey);
     84        psU8 bit = psMetadataLookupU8 (&status, header, valuekey);
     85
     86        // XXX validate that bit is a 2^n value?
     87
     88        psMetadataItem *item = psMetadataLookup (header, name);
     89        if (!item) {
     90            psWarning("mask recipe entry %s not in recipe\n", name);
     91            psMetadataAddU8 (recipe, PS_LIST_TAIL, name, 0, "Bitmask bit value", bit);
     92        } else {
     93            item->data.U8 = bit;
     94        }
     95    }
     96   
     97    return true;
     98}
     99
     100// write the named mask bits to the header
     101bool pmConfigMaskWriteHeader (pmConfig *config, psMetadata *header) {
     102
     103    char namekey[80];
     104    char valuekey[80];
     105
     106    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
     107    if (!recipe) {
     108        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
     109        return false;
     110    }
     111
     112    int nMask = 0;
     113
     114    psMetadataIterator *iter = psMetadataIteratorAlloc(recipe, PS_LIST_HEAD, NULL); // Iterator
     115
     116    psMetadataItem *item;               // Item from iteration
     117    while ((item = psMetadataGetAndIncrement(iter))) {
     118
     119        if (item->type != PS_DATA_U8) {
     120            psWarning("mask recipe entry %s is not a bit value\n", item->name);
     121            continue;
     122        }
     123
     124        snprintf (namekey,  64, "MSKNAM%02d", nMask);
     125        snprintf (valuekey, 64, "MSKVAL%02d", nMask);
     126
     127        psMetadataAddStr (header, PS_LIST_TAIL, namekey, 0, "Bitmask bit name", item->name);
     128        psMetadataAddU8 (header, PS_LIST_TAIL, valuekey, 0, "Bitmask bit value", item->data.U8);
     129        nMask ++;
     130    }
     131   
     132    psMetadataAddS32 (header, PS_LIST_TAIL, "MSKNUM", 0, "Bitmask bit count", nMask);
     133    return true;
     134}
     135
     136// examine named mask values in mask recipe and set the bits for maskValue and markValue
     137// this function sets an appropriate value for the following required named mask concepts:
     138// FLAT (used to mark out-of-range corrections in the flat-fielding)
     139// BLANK (used to mark non-existent pixels)
     140// SAT (used to mark pixels with values out-of-range on the high end)
     141// BAD (used to mark pixels with values out-of-range on the low end)
     142// If there is no explicit value for the above, the 'DETECTOR' and 'RANGE' bits are used
     143// If these latter do not exist, the value 0x01 is used.
     144// The values actually used for these names are written back to the config file
     145bool pmConfigMaskSetBits (psMaskType *outMaskValue, psMaskType *outMarkValue, pmConfig *config) {
     146
     147    psMaskType maskValue = 0;
     148
     149    // mask for generic detector defect
     150    psMaskType detectorMask = pmConfigMaskGet("DETECTOR", config);
     151    maskValue |= detectorMask;
     152
     153    // mask for dark structures
     154    psMaskType darkMask = pmConfigMaskGet("DARK", config);
     155    maskValue |= darkMask;
     156
     157    // mask for non-linear flat regions (default to DETECTOR if not defined)
     158    psMaskType flatMask = pmConfigMaskGet("FLAT", config);
     159    if (!flatMask) {
     160        flatMask = detectorMask;
     161        pmConfigMaskSet (config, "FLAT", flatMask);
     162    }
     163    if (!flatMask) {
     164        flatMask = 0x01;
     165        pmConfigMaskSet (config, "FLAT", flatMask);
     166    }
     167    maskValue |= flatMask;
     168
     169    // mask for non-existent data  (default to DETECTOR if not defined)
     170    psMaskType blankMask = pmConfigMaskGet("BLANK", config);
     171    if (!blankMask) {
     172        blankMask = detectorMask;
     173        pmConfigMaskSet (config, "BLANK", blankMask);
     174    }
     175    if (!blankMask) {
     176        blankMask = 0x01;
     177        pmConfigMaskSet (config, "BLANK", blankMask);
     178    }
     179    maskValue |= blankMask;
     180
     181    // mask for generic data range errors
     182    psMaskType rangeMask = pmConfigMaskGet("RANGE", config);
     183    maskValue |= rangeMask;
     184
     185    // mask for saturated data  (default to RANGE if not defined)
     186    psMaskType satMask = pmConfigMaskGet("SAT", config);
     187    if (!satMask) {
     188        satMask = rangeMask;
     189        pmConfigMaskSet (config, "SAT", satMask);
     190    }
     191    if (!satMask) {
     192        satMask = 0x01;
     193        pmConfigMaskSet (config, "SAT", satMask);
     194    }
     195    maskValue |= satMask;
     196   
     197    // mask for below-range data  (default to RANGE if not defined)
     198    psMaskType badMask = pmConfigMaskGet("BAD", config);
     199    if (!badMask) {
     200        badMask = rangeMask;
     201        pmConfigMaskSet (config, "BAD", badMask);
     202    }
     203    if (!badMask) {
     204        badMask = 0x01;
     205        pmConfigMaskSet (config, "BAD", badMask);
     206    }
     207    maskValue |= badMask;
     208
     209    // XXX not sure what to do with these
     210    psMaskType crMask = pmConfigMaskGet("CR", config);
     211    maskValue |= crMask;
     212
     213    psMaskType ghostMask = pmConfigMaskGet("GHOST", config);
     214    maskValue |= ghostMask;
     215
     216    // search for an unset bit to use for MARK:
     217    psMaskType markValue = 0x80;
     218
     219    int nBits = sizeof(psMaskType) * 8;
     220    for (int i = 0; !markValue && (i < nBits); i++) {
     221        if (maskValue & markValue) {
     222            markValue >>= 1;
     223        } else {
     224            markValue = markValue;
     225        }
     226    }
     227    if (!markValue) {
     228        psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!");
     229        return false;
     230    }
     231
     232    // update the config table
     233    pmConfigMaskSet (config, "MASK.VALUE", maskValue);
     234    pmConfigMaskSet (config, "MARK.VALUE", markValue);
     235
     236    *outMaskValue = maskValue;
     237    *outMarkValue = markValue;
     238
     239    return true;
     240}
Note: See TracChangeset for help on using the changeset viewer.