IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 13, 2007, 4:03:29 PM (19 years ago)
Author:
Paul Price
Message:

Adding dark normalisation. The idea is that the dark current is not always linear with the darktime, but may be described by a polynomial function of the darktime. We introduce in the camera configuration DARK.NORM, which is a filename within the search path (or it may be a metadata, which removes the need to read a file, but clutters the configuration file). This file is read in the usual course of configuration setup. When required, DARK.NORM.KEY (which is resolved in the usual way, so try, e.g., '{CHIP.NAME}') points at a metadata within the DARK.NORM that provides the polynomial for correcting the darktime. This means that the view must be passed in to pmBiasSubtract, so that the appropriate polynomial can be identified.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/pmBias.c

    r13774 r13810  
    1111#include "pmFPA.h"
    1212#include "pmHDUUtils.h"
     13#include "pmFPALevel.h"
     14#include "pmFPAview.h"
     15#include "pmFPACalibration.h"
     16
    1317#include "pmBias.h"
    1418
     
    206210}
    207211
    208 
    209 bool pmBiasSubtract(pmReadout *in, pmOverscanOptions *overscanOpts,
    210                     const pmReadout *bias, const pmReadout *dark)
     212bool pmBiasSubtract(pmReadout *inRO, pmOverscanOptions *overscanOpts,
     213                    const pmReadout *biasRO, const pmReadout *darkRO, const pmFPAview *view)
    211214{
    212215    psTrace("psModules.detrend", 4,
    213216            "---- pmBiasSubtract() begin ----\n");
    214     PS_ASSERT_PTR_NON_NULL(in, NULL);
    215     PS_ASSERT_IMAGE_NON_NULL(in->image, NULL);
    216     PS_ASSERT_IMAGE_TYPE(in->image, PS_TYPE_F32, NULL);
    217     if (bias) {
    218         PS_ASSERT_IMAGE_NON_NULL(bias->image, NULL);
    219         PS_ASSERT_IMAGE_TYPE(bias->image, PS_TYPE_F32, NULL);
    220     }
    221     if (dark) {
    222         PS_ASSERT_IMAGE_NON_NULL(dark->image, NULL);
    223         PS_ASSERT_IMAGE_TYPE(dark->image, PS_TYPE_F32, NULL);
    224     }
    225 
    226     pmHDU *hdu = pmHDUFromReadout(in);  // HDU of interest
    227 
    228     psImage *image = in->image;         // The input image
     217
     218    PS_ASSERT_PTR_NON_NULL(inRO, false);
     219    PS_ASSERT_IMAGE_NON_NULL(inRO->image, false);
     220    PS_ASSERT_IMAGE_TYPE(inRO->image, PS_TYPE_F32, false);
     221    if (biasRO) {
     222        PS_ASSERT_IMAGE_NON_NULL(biasRO->image, false);
     223        PS_ASSERT_IMAGE_TYPE(biasRO->image, PS_TYPE_F32, false);
     224    }
     225    if (darkRO) {
     226        PS_ASSERT_PTR_NON_NULL(view, false);
     227        PS_ASSERT_IMAGE_NON_NULL(darkRO->image, false);
     228        PS_ASSERT_IMAGE_TYPE(darkRO->image, PS_TYPE_F32, false);
     229    }
     230
     231    pmHDU *hdu = pmHDUFromReadout(inRO);  // HDU of interest
     232    psImage *image = inRO->image;         // The input image
    229233
    230234    // Overscan processing
     
    238242        }
    239243
    240         psList *overscans = in->bias; // List of the overscan images
     244        psList *overscans = inRO->bias; // List of the overscan images
    241245
    242246        psStatsOptions statistic = psStatsSingleOption(overscanOpts->stat->options); // Statistic to use
     
    281285            psFree(comment);
    282286
    283             // write metadata header value
    284             psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan value", reduced);
     287            // write metadata header value
     288            psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan value",
     289                             reduced);
    285290            psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", NAN);
    286291
     
    288293        } else {
    289294            // We do the regular overscan subtraction
    290             bool readRows = psMetadataLookupBool(NULL, in->parent->concepts, "CELL.READDIR");// Read direction
     295            bool readRows = psMetadataLookupBool(NULL, inRO->parent->concepts,
     296                                                 "CELL.READDIR"); // Read direction
    291297            float chi2 = NAN;           // chi^2 from fit
    292298
     
    302308                psImage *overscan = NULL; // Overscan image from iterator
    303309                while ((overscan = psListGetAndIncrement(iter))) {
    304                     // the overscan and image might not be aligned.  pixels->data represents
    305                     // the image row pixels.
     310                    // the overscan and image might not be aligned.  pixels->data represents
     311                    // the image row pixels.
    306312                    int diff = overscan->row0 - image->row0; // Offset between the two regions
    307313                    for (int i = PS_MAX(0,diff); i < PS_MIN(image->numRows, overscan->numRows + diff); i++) {
    308                         int j = i - diff;
     314                        int j = i - diff;
    309315                        // i is row on image
    310                         // j is row on overscan
     316                        // j is row on overscan
    311317                        psVector *values = pixels->data[i];
    312318                        int index = values->n; // Index in the vector
     
    349355                psImage *overscan = NULL; // Overscan image from iterator
    350356                while ((overscan = psListGetAndIncrement(iter))) {
    351                     // the overscan and image might not be aligned.  pixels->data represents
    352                     // the image row pixels.
     357                    // the overscan and image might not be aligned.  pixels->data represents
     358                    // the image row pixels.
    353359                    int diff = overscan->col0 - image->col0; // Offset between the two regions
    354360                    for (int i = PS_MAX(0,diff); i < PS_MIN(image->numCols, overscan->numCols + diff); i++) {
    355                         int I = i - diff;
     361                        int iFixed = i - diff;
    356362                        // i is column on image
    357                         // I is column on overscan
     363                        // iFixed is column on overscan
    358364                        psVector *values = pixels->data[i];
    359365                        int index = values->n; // Index in the vector
    360366                        values = psVectorRealloc(values, values->n + overscan->numRows);
    361                         for (int J = 0; J < overscan->numRows; J++) {
    362                             values->data.F32[index++] = overscan->data.F32[J][I];
     367                        for (int j = 0; j < overscan->numRows; j++) {
     368                            values->data.F32[index++] = overscan->data.F32[j][iFixed];
    363369                        }
    364370                        values->n += overscan->numRows;
     
    397403                    psFree(comment);
    398404
    399                     // write metadata header value
    400                     psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan value", poly->coeff[0]);
    401                     psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", poly->coeffErr[0]);
     405                    // write metadata header value
     406                    psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE,
     407                                     "Overscan value", poly->coeff[0]);
     408                    psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE,
     409                                     "Overscan stdev", poly->coeffErr[0]);
    402410                    break;
    403411                }
     
    414422                        psFree(comment);
    415423                    }
    416                     // write metadata header value
    417                     psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan value", NAN);
    418                     psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", NAN);
     424                    // write metadata header value
     425                    psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE,
     426                                     "Overscan value", NAN);
     427                    psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE,
     428                                     "Overscan stdev", NAN);
    419429                    break;
    420430                }
     
    431441
    432442    // Bias frame subtraction
    433     if (bias) {
    434         psVector *md5 = psImageMD5(bias->image); // md5 hash
     443    if (biasRO) {
     444        psVector *md5 = psImageMD5(biasRO->image); // md5 hash
    435445        psString md5string = psMD5toString(md5); // String
    436446        psFree(md5);
     
    440450        psFree(md5string);
    441451
    442         if (!subtractFrame(in, bias, 1.0)) {
     452        if (!subtractFrame(inRO, biasRO, 1.0)) {
    443453            return false;
    444454        }
    445455    }
    446456
    447     if (dark) {
     457    if (darkRO) {
    448458        // Get the scaling
    449         float inTime = psMetadataLookupF32(NULL, in->parent->concepts, "CELL.DARKTIME");
    450         float darkTime = psMetadataLookupF32(NULL, dark->parent->concepts, "CELL.DARKTIME");
    451 
    452         psVector *md5 = psImageMD5(dark->image); // md5 hash
     459        float inTime = psMetadataLookupF32(NULL, inRO->parent->concepts, "CELL.DARKTIME");
     460        float darkTime = psMetadataLookupF32(NULL, darkRO->parent->concepts, "CELL.DARKTIME");
     461        if (isnan(inTime) || isnan(darkTime)) {
     462            psError(PS_ERR_UNKNOWN, false, "Unable to determine dark scaling.");
     463            return false;
     464        }
     465
     466        float inNorm = pmFPADarkNorm(inRO->parent->parent->parent, view, inTime);
     467        float darkNorm = pmFPADarkNorm(darkRO->parent->parent->parent, view, darkTime);
     468        if (isnan(inNorm) || isnan(darkNorm)) {
     469            psError(PS_ERR_UNKNOWN, false, "Unable to determine dark normalisations.");
     470            return false;
     471        }
     472
     473        float scale = inNorm / darkNorm;// Scaling to apply to dark exposure
     474
     475        psVector *md5 = psImageMD5(darkRO->image); // md5 hash
    453476        psString md5string = psMD5toString(md5); // String
    454477        psFree(md5);
    455         psStringPrepend(&md5string, "DARK image (scale %.3f) MD5: ", inTime/darkTime);
     478        psStringPrepend(&md5string, "DARK image (scale %.3f) MD5: ", scale);
    456479        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK,
    457480                         md5string, "");
    458481        psFree(md5string);
    459482
    460         if (!subtractFrame(in, dark, inTime/darkTime)) {
     483        if (!subtractFrame(inRO, darkRO, scale)) {
    461484            return false;
    462485        }
Note: See TracChangeset for help on using the changeset viewer.