IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 4, 2010, 8:59:31 PM (16 years ago)
Author:
Paul Price
Message:

Adding code to tweak background of nominated cells within a chip to match the mean of the rest, which I call 'cell pattern correction'. The old 'pattern correction' has effectively been renamed as 'row pattern correction'.

Location:
branches/eam_branches/20091201/psModules/src/detrend
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20091201/psModules/src/detrend/pmPattern.c

    r26731 r26776  
    127127    return true;
    128128}
     129
     130
     131
     132
     133bool pmPatternCell(pmChip *chip, const psVector *tweak, psStatsOptions bgStat, psStatsOptions cellStat,
     134                   psImageMaskType maskVal, psImageMaskType maskBad)
     135{
     136    PS_ASSERT_PTR_NON_NULL(chip, false);
     137    PS_ASSERT_VECTOR_NON_NULL(tweak, false);
     138    PS_ASSERT_VECTOR_SIZE(tweak, chip->cells->n, false);
     139    PS_ASSERT_VECTOR_TYPE(tweak, PS_TYPE_U8, false);
     140
     141    int numCells = tweak->n;            // Number of cells
     142
     143    psVector *mean = psVectorAlloc(numCells, PS_TYPE_F32); // Mean for each cell
     144    psVector *meanMask = psVectorAlloc(numCells, PS_TYPE_VECTOR_MASK); // Mask for means
     145    psVectorInit(mean, NAN);
     146    psVectorInit(meanMask, 0);
     147
     148    // Mask bits
     149    enum {
     150        PM_PATTERN_IGNORE = 0x01,       // Ignore this cell
     151        PM_PATTERN_TWEAK  = 0x02,       // Tweak this cell
     152        PM_PATTERN_ERROR  = 0x04,       // Error in calculating background
     153        PM_PATTERN_ALL    = 0xFF,       // All causes
     154    };
     155
     156    // Count number of cells to tweak
     157    int numTweak = 0;                   // Number of cells to tweak
     158    int numIgnore = 0;                  // Number of cells to ignore
     159    for (int i = 0; i < numCells; i++) {
     160        pmCell *cell = chip->cells->data[i]; // Cell of interest
     161        if (!cell || !cell->data_exists || !cell->process ||
     162            cell->readouts->n == 0 || cell->readouts->n > 1 || !cell->readouts->data[0]) {
     163            numIgnore++;
     164            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_IGNORE;
     165            continue;
     166        }
     167        if (tweak->data.U8[i]) {
     168            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_TWEAK;
     169            numTweak++;
     170        }
     171    }
     172    if (numTweak == 0) {
     173        // Nothing to do
     174        psFree(mean);
     175        psFree(meanMask);
     176        return true;
     177    }
     178    if (numTweak >= numCells - numIgnore) {
     179        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot pattern-correct all cells within a chip.");
     180        psFree(mean);
     181        psFree(meanMask);
     182        return false;
     183    }
     184
     185    // Measure mean of each cell
     186    // This is not really the perfect thing to do, which would be to take a common mean for the set of cells
     187    // which aren't being tweaked (because some cells will be heavily masked, so shouldn't be weighted the
     188    // same as pure cells), but it's simple and fast.
     189    psStats *bgStats = psStatsAlloc(bgStat); // Statistics on background
     190    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
     191    for (int i = 0; i < numCells; i++) {
     192        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) {
     193            continue;
     194        }
     195        pmCell *cell = chip->cells->data[i]; // Cell of interest
     196        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     197
     198        psStatsInit(bgStats);
     199#if 1
     200        if (!psImageBackground(bgStats, NULL, ro->image, ro->mask, maskVal, rng)) {
     201            psWarning("Unable to measure background for cell %d\n", i);
     202            psErrorClear();
     203            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     204            continue;
     205        }
     206#else
     207        if (!psImageStats(bgStats, ro->image, ro->mask, maskVal)) {
     208            psWarning("Unable to measure background for cell %d\n", i);
     209            psErrorClear();
     210            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     211            continue;
     212        }
     213#endif
     214        mean->data.F32[i] = psStatsGetValue(bgStats, bgStat);
     215        if (!isfinite(mean->data.F32[i])) {
     216            psWarning("Non-finite background for cell %d\n", i);
     217            psErrorClear();
     218            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     219            continue;
     220        }
     221    }
     222    psFree(bgStats);
     223    psFree(rng);
     224
     225    psStats *cellStats = psStatsAlloc(cellStat); // Statistics on cells
     226    if (!psVectorStats(cellStats, mean, NULL, meanMask, PM_PATTERN_ALL)) {
     227        psError(PS_ERR_UNKNOWN, false, "Unable to calculate mean cell background.");
     228        psFree(mean);
     229        psFree(meanMask);
     230        psFree(cellStats);
     231        return false;
     232    }
     233
     234    float background = psStatsGetValue(cellStats, cellStat); // Background value for chip
     235    psFree(cellStats);
     236    if (!isfinite(background)) {
     237        psError(PS_ERR_UNKNOWN, false, "Non-finite mean cell background.");
     238        psFree(mean);
     239        psFree(meanMask);
     240        return false;
     241    }
     242
     243    psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Mean chip background is %f", background);
     244
     245    for (int i = 0; i < numCells; i++) {
     246        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) {
     247            continue;
     248        }
     249        if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_TWEAK)) {
     250            continue;
     251        }
     252        pmCell *cell = chip->cells->data[i]; // Cell of interest
     253        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     254        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_ERROR) {
     255            psImageInit(ro->image, NAN);
     256            psBinaryOp(ro->mask, ro->mask, "|", psScalarAlloc(maskBad, PS_TYPE_IMAGE_MASK));
     257            continue;
     258        }
     259        float correction = background - mean->data.F32[i]; // Correction to apply
     260        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Correcting background of cell %d by %f", i, correction);
     261        psBinaryOp(ro->image, ro->image, "+", psScalarAlloc(correction, PS_TYPE_F32));
     262    }
     263
     264    psFree(mean);
     265    psFree(meanMask);
     266
     267    return true;
     268}
  • branches/eam_branches/20091201/psModules/src/detrend/pmPattern.h

    r24903 r26776  
    3131    );
    3232
     33/// Fix the background on cells known to be troublesome
     34bool pmPatternCell(
     35    pmChip *chip,                       ///< Chip to correct
     36    const psVector *tweak,              ///< U8 vector indicating whether to tweak the corresponding cell
     37    psStatsOptions bgStat,              ///< Statistic to use for background measurement
     38    psStatsOptions cellStat,            ///< Statistic to use for combination of cell background measurements
     39    psImageMaskType maskVal,            ///< Mask value to use
     40    psImageMaskType maskBad             ///< Mask value to give bad pixels
     41    );
     42
     43
    3344/// @}
    3445#endif
Note: See TracChangeset for help on using the changeset viewer.