IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:50:52 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/psModules

  • branches/simtest_nebulous_branches/psModules/src/detrend/pmPattern.c

    r24905 r27840  
    11#include <stdio.h>
     2#include <string.h>
    23#include <pslib.h>
    34
     
    910// Mask a row as bad
    1011static void patternMaskRow(pmReadout *ro, // Readout to mask
    11                            int y,         // Row to mask
     12                           int y,       // Row to mask
    1213                           psImageMaskType bad // Mask value to give
    1314                           )
     
    1718    psAssert(y < image->numRows, "Row not in image");
    1819
    19     int numCols = image->numCols;       // Size of image
     20    int numCols = image->numCols;       // Number of columns
    2021    for (int x = 0; x < numCols; x++) {
    2122        image->data.F32[y][x] = NAN;
     
    2930    return;
    3031}
     32
     33//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     34// Measurement and application
     35//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    3136
    3237bool pmPatternRow(pmReadout *ro, int order, int iter, float rej, float thresh,
     
    6368    float lower = stats->robustMedian - thresh * stats->robustStdev; // Lower bound for data
    6469    float upper = stats->robustMedian + thresh * stats->robustStdev; // Upper bound for data
     70    float background = stats->robustMedian;
    6571    psFree(stats);
    6672    psFree(rng);
     
    7985    psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, order); // Polynomial to fit
    8086    psVector *data = psVectorAlloc(numCols, PS_TYPE_F32); // Data to fit
     87
     88    psImage *corr = psImageAlloc(order + 1, numRows, PS_TYPE_F64); // Corrections applied
     89    psImageInit(corr, NAN);
    8190
    8291    for (int y = 0; y < numRows; y++) {
     
    104113            continue;
    105114        }
     115
     116        poly->coeff[0] -= background;
     117        memcpy(corr->data.F64[y], poly->coeff, (order + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F64));
    106118        psVector *solution = psPolynomial1DEvalVector(poly, indices); // Solution vector
    107119        if (!solution) {
     
    117129        psFree(solution);
    118130    }
     131
     132    psMetadataAddImage(ro->analysis, PS_LIST_TAIL, PM_PATTERN_ROW_CORRECTION, PS_META_REPLACE,
     133                       "Pattern row correction", corr);
     134    psFree(corr);
    119135
    120136    psFree(indices);
     
    126142    return true;
    127143}
     144
     145bool pmPatternRowApply(pmReadout *ro, psImageMaskType maskBad)
     146{
     147    PM_ASSERT_READOUT_NON_NULL(ro, false);
     148    PM_ASSERT_READOUT_IMAGE(ro, false);
     149
     150    bool mdok;                          // Status of MD lookup
     151    psImage *corr = psMetadataLookupPtr(&mdok, ro->analysis, PM_PATTERN_ROW_CORRECTION); // Correction
     152    if (!mdok) {
     153        // No correction to apply
     154        return true;
     155    }
     156
     157    psImage *image = ro->image; // Image of interest
     158    int numCols = image->numCols, numRows = image->numRows; // Size of image
     159
     160    if (corr->numRows != numRows) {
     161        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     162                "Number of rows of image (%d) does not match number of rows of pattern correction (%d)\n",
     163                numRows, corr->numRows);
     164        return false;
     165    }
     166
     167    int order = corr->numCols - 1;                                        // Polynomial order
     168    psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, order); // Polynomial to apply
     169    psVector *indices = psVectorAlloc(numCols, PS_TYPE_F32); // Indices for polynomial
     170    float norm = 2.0 / (float)numCols;  // Normalisation for indices
     171    for (int x = 0; x < numCols; x++) {
     172        indices->data.F32[x] = x * norm - 1.0;
     173    }
     174
     175    for (int y = 0; y < numRows; y++) {
     176        memcpy(poly->coeff, corr->data.F64[y], (order + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F64));
     177        psVector *solution = psPolynomial1DEvalVector(poly, indices); // Solution vector
     178        if (!solution) {
     179            psWarning("Unable to evaluate polynomial for row %d", y);
     180            psErrorClear();
     181            patternMaskRow(ro, y, maskBad);
     182            continue;
     183        }
     184
     185        for (int x = 0; x < numCols; x++) {
     186            image->data.F32[y][x] -= solution->data.F32[x];
     187        }
     188        psFree(solution);
     189    }
     190
     191    psFree(poly);
     192    psFree(indices);
     193
     194    return true;
     195}
     196
     197
     198bool pmPatternCell(pmChip *chip, const psVector *tweak, psStatsOptions bgStat, psStatsOptions cellStat,
     199                   psImageMaskType maskVal, psImageMaskType maskBad)
     200{
     201    PS_ASSERT_PTR_NON_NULL(chip, false);
     202    PS_ASSERT_VECTOR_NON_NULL(tweak, false);
     203    PS_ASSERT_VECTOR_SIZE(tweak, chip->cells->n, false);
     204    PS_ASSERT_VECTOR_TYPE(tweak, PS_TYPE_U8, false);
     205
     206    int numCells = tweak->n;            // Number of cells
     207
     208    psVector *mean = psVectorAlloc(numCells, PS_TYPE_F32); // Mean for each cell
     209    psVector *meanMask = psVectorAlloc(numCells, PS_TYPE_VECTOR_MASK); // Mask for means
     210    psVectorInit(mean, NAN);
     211    psVectorInit(meanMask, 0);
     212
     213    // Mask bits
     214    enum {
     215        PM_PATTERN_IGNORE = 0x01,       // Ignore this cell
     216        PM_PATTERN_TWEAK  = 0x02,       // Tweak this cell
     217        PM_PATTERN_ERROR  = 0x04,       // Error in calculating background
     218        PM_PATTERN_ALL    = 0xFF,       // All causes
     219    };
     220
     221    // Count number of cells to tweak
     222    int numTweak = 0;                   // Number of cells to tweak
     223    int numIgnore = 0;                  // Number of cells to ignore
     224    for (int i = 0; i < numCells; i++) {
     225        pmCell *cell = chip->cells->data[i]; // Cell of interest
     226        if (!cell || !cell->data_exists || !cell->process ||
     227            cell->readouts->n == 0 || cell->readouts->n > 1 || !cell->readouts->data[0]) {
     228            numIgnore++;
     229            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_IGNORE;
     230            continue;
     231        }
     232        if (tweak->data.U8[i]) {
     233            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_TWEAK;
     234            numTweak++;
     235        }
     236    }
     237    if (numTweak == 0) {
     238        // Nothing to do
     239        psFree(mean);
     240        psFree(meanMask);
     241        return true;
     242    }
     243    if (numTweak >= numCells - numIgnore) {
     244        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot pattern-correct all cells within a chip.");
     245        psFree(mean);
     246        psFree(meanMask);
     247        return false;
     248    }
     249
     250    // Measure mean of each cell
     251    // This is not really the perfect thing to do, which would be to take a common mean for the set of cells
     252    // which aren't being tweaked (because some cells will be heavily masked, so shouldn't be weighted the
     253    // same as pure cells), but it's simple and fast.
     254    psStats *bgStats = psStatsAlloc(bgStat); // Statistics on background
     255    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
     256    for (int i = 0; i < numCells; i++) {
     257        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) {
     258            continue;
     259        }
     260        pmCell *cell = chip->cells->data[i]; // Cell of interest
     261        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     262
     263        psStatsInit(bgStats);
     264#if 1
     265        if (!psImageBackground(bgStats, NULL, ro->image, ro->mask, maskVal, rng)) {
     266            psWarning("Unable to measure background for cell %d\n", i);
     267            psErrorClear();
     268            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     269            continue;
     270        }
     271#else
     272        if (!psImageStats(bgStats, ro->image, ro->mask, maskVal)) {
     273            psWarning("Unable to measure background for cell %d\n", i);
     274            psErrorClear();
     275            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     276            continue;
     277        }
     278#endif
     279        mean->data.F32[i] = psStatsGetValue(bgStats, bgStat);
     280        if (!isfinite(mean->data.F32[i])) {
     281            psWarning("Non-finite background for cell %d\n", i);
     282            psErrorClear();
     283            meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR;
     284            continue;
     285        }
     286    }
     287    psFree(bgStats);
     288    psFree(rng);
     289
     290    psStats *cellStats = psStatsAlloc(cellStat); // Statistics on cells
     291    if (!psVectorStats(cellStats, mean, NULL, meanMask, PM_PATTERN_ALL)) {
     292        // an error in psVectorStats implies a programming error
     293        psError(PS_ERR_UNKNOWN, false, "Unable to calculate mean cell background.");
     294        psFree(mean);
     295        psFree(meanMask);
     296        psFree(cellStats);
     297        return false;
     298    }
     299
     300    float background = psStatsGetValue(cellStats, cellStat); // Background value for chip
     301    psFree(cellStats);
     302    if (!isfinite(background)) {
     303        // this can happen if all data in the image is bad -- in this case, do not correct, but
     304        // do not treat this as an error (other functions are responsible for check data validity)
     305        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Non-finite mean cell background -- skipping correction (data probabaly bad).");
     306        psFree(mean);
     307        psFree(meanMask);
     308        return true;
     309    }
     310
     311    psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Mean chip background is %f", background);
     312
     313    for (int i = 0; i < numCells; i++) {
     314        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) {
     315            continue;
     316        }
     317        if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_TWEAK)) {
     318            continue;
     319        }
     320        pmCell *cell = chip->cells->data[i]; // Cell of interest
     321        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     322        if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_ERROR) {
     323            psImageInit(ro->image, NAN);
     324            psBinaryOp(ro->mask, ro->mask, "|", psScalarAlloc(maskBad, PS_TYPE_IMAGE_MASK));
     325            psMetadataAddF32(ro->analysis, PS_LIST_TAIL, PM_PATTERN_CELL_CORRECTION, PS_META_REPLACE,
     326                             "Pattern cell correction solution", NAN);
     327            continue;
     328        }
     329        float correction = background - mean->data.F32[i]; // Correction to apply
     330        const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
     331        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Correcting background of cell %s by %f",
     332                 cellName, correction);
     333        psBinaryOp(ro->image, ro->image, "+", psScalarAlloc(correction, PS_TYPE_F32));
     334        psMetadataAddF32(ro->analysis, PS_LIST_TAIL, PM_PATTERN_CELL_CORRECTION, PS_META_REPLACE,
     335                         "Pattern cell correction solution", correction);
     336    }
     337
     338    psFree(mean);
     339    psFree(meanMask);
     340
     341    return true;
     342}
     343
     344bool pmPatternCellApply(pmReadout *ro, psImageMaskType maskBad)
     345{
     346    PM_ASSERT_READOUT_NON_NULL(ro, false);
     347    PM_ASSERT_READOUT_IMAGE(ro, false);
     348
     349    bool mdok;                          // Status of MD lookup
     350    float corr = psMetadataLookupF32(&mdok, ro->analysis, PM_PATTERN_CELL_CORRECTION); // Correction to apply
     351    if (!mdok) {
     352        // No correction to apply
     353        return true;
     354    }
     355
     356    psImage *image = ro->image, *mask = ro->mask; // Image and mask of interest
     357    int numCols = image->numCols, numRows = image->numRows; // Size of image
     358
     359    if (!isfinite(corr)) {
     360        for (int y = 0; y < numRows; y++) {
     361            for (int x = 0; x < numCols; x++) {
     362                image->data.F32[y][x] = NAN;
     363            }
     364        }
     365        if (mask) {
     366            for (int y = 0; y < numRows; y++) {
     367                for (int x = 0; x < numCols; x++) {
     368                    mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskBad;
     369                }
     370            }
     371        }
     372    } else {
     373        for (int y = 0; y < numRows; y++) {
     374            for (int x = 0; x < numCols; x++) {
     375                image->data.F32[y][x] += corr;
     376            }
     377        }
     378    }
     379
     380    return true;
     381}
     382
     383
Note: See TracChangeset for help on using the changeset viewer.