IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 13810


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.

Location:
trunk/psModules/src
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/Makefile.am

    r12454 r13810  
    55libpsmodulescamera_la_SOURCES  = \
    66        pmFPA.c \
     7        pmFPACalibration.c \
    78        pmFPAConstruct.c \
    89        pmFPACopy.c \
     
    2930pkginclude_HEADERS = \
    3031        pmFPA.h \
     32        pmFPACalibration.h \
    3133        pmFPAConstruct.h \
    3234        pmFPACopy.h \
  • trunk/psModules/src/camera/pmFPAfile.c

    r13523 r13810  
    55#include <stdio.h>
    66#include <string.h>
    7 #include <strings.h>            /* for strn?casecmp */
     7#include <strings.h>            /* for strn?casecmp */
    88#include <pslib.h>
    99
     
    164164}
    165165
    166 // select the rule from the camera configuration, perform substitutions as needed
    167 psString pmFPAfileNameFromRule(const char *rule, const pmFPAfile *file, const pmFPAview *view)
    168 {
    169     PS_ASSERT_PTR_NON_NULL(rule, NULL);
    170     PS_ASSERT_INT_POSITIVE(strlen(rule), NULL);
    171     PS_ASSERT_PTR_NON_NULL(file, NULL);
     166psString pmFPANameFromRule(const char *rule, const pmFPA *fpa, const pmFPAview *view)
     167{
     168    PS_ASSERT_STRING_NON_EMPTY(rule, NULL);
    172169    PS_ASSERT_PTR_NON_NULL(view, NULL);
    173170
    174     char *newName = NULL;     // destination for resulting name
    175 
    176     newName = psStringCopy (rule);
    177 
    178     if (strstr (newName, "{OUTPUT}") != NULL) {
    179         char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
    180         if (name != NULL) {
    181             psStringSubstitute(&newName, name, "{OUTPUT}");
    182         }
    183     }
     171    psString newName = NULL;            // New name, to be returned
     172    newName = psStringCopy(rule);
     173
    184174    if (strstr (newName, "{CHIP.NAME}") != NULL) {
    185         pmChip *chip = pmFPAviewThisChip (view, file->fpa);
     175        pmChip *chip = pmFPAviewThisChip (view, fpa);
    186176        if (chip != NULL) {
    187177            char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
     
    202192    }
    203193    if (strstr (newName, "{CELL.NAME}") != NULL) {
    204         pmCell *cell = pmFPAviewThisCell (view, file->fpa);
     194        pmCell *cell = pmFPAviewThisCell (view, fpa);
    205195        if (cell != NULL) {
    206196            char *name = psMetadataLookupStr (NULL, cell->concepts, "CELL.NAME");
     
    220210    }
    221211    if (strstr (newName, "{EXTNAME}") != NULL) {
    222         pmHDU *hdu = pmFPAviewThisHDU (view, file->fpa);
     212        pmHDU *hdu = pmFPAviewThisHDU (view, fpa);
    223213        if (hdu->extname && *hdu->extname) {
    224214            psStringSubstitute(&newName, hdu->extname, "{EXTNAME}");
     
    226216    }
    227217    if (strstr (newName, "{FILTER}") != NULL) {
    228         if (file->fpa != NULL) {
    229             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.FILTER");
     218        if (fpa != NULL) {
     219            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.FILTER");
    230220            if (name && *name) {
    231221                psStringSubstitute(&newName, name, "{FILTER}");
     
    234224    }
    235225    if (strstr (newName, "{FILTER.ID}") != NULL) {
    236         if (file->fpa != NULL) {
    237             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.FILTERID");
     226        if (fpa != NULL) {
     227            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.FILTERID");
    238228            if (name && *name) {
    239229                psStringSubstitute(&newName, name, "{FILTER.ID}");
     
    242232    }
    243233    if (strstr (newName, "{CAMERA}") != NULL) {
    244         if (file->fpa != NULL) {
    245             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.INSTRUMENT");
     234        if (fpa != NULL) {
     235            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.INSTRUMENT");
    246236            if (name && *name) {
    247237                psStringSubstitute(&newName, name, "{CAMERA}");
     
    250240    }
    251241    if (strstr (newName, "{INSTRUMENT}") != NULL) {
    252         if (file->fpa != NULL) {
    253             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.INSTRUMENT");
     242        if (fpa != NULL) {
     243            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.INSTRUMENT");
    254244            if (name && *name) {
    255245                psStringSubstitute(&newName, name, "{INSTRUMENT}");
     
    258248    }
    259249    if (strstr (newName, "{DETECTOR}") != NULL) {
    260         if (file->fpa != NULL) {
    261             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.DETECTOR");
     250        if (fpa != NULL) {
     251            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.DETECTOR");
    262252            if (name && *name) {
    263253                psStringSubstitute(&newName, name, "{DETECTOR}");
     
    266256    }
    267257    if (strstr (newName, "{TELESCOPE}") != NULL) {
    268         if (file->fpa != NULL) {
    269             char *name = psMetadataLookupStr (NULL, file->fpa->concepts, "FPA.TELESCOPE");
     258        if (fpa != NULL) {
     259            char *name = psMetadataLookupStr (NULL, fpa->concepts, "FPA.TELESCOPE");
    270260            if (name && *name) {
    271261                psStringSubstitute(&newName, name, "{TELESCOPE}");
     
    273263        }
    274264    }
     265    return newName;
     266}
     267
     268// select the rule from the camera configuration, perform substitutions as needed
     269psString pmFPAfileNameFromRule(const char *rule, const pmFPAfile *file, const pmFPAview *view)
     270{
     271    PS_ASSERT_PTR_NON_NULL(rule, NULL);
     272    PS_ASSERT_INT_POSITIVE(strlen(rule), NULL);
     273    PS_ASSERT_PTR_NON_NULL(file, NULL);
     274    PS_ASSERT_PTR_NON_NULL(view, NULL);
     275
     276    psString newRule = NULL;            // Rule to pass on to pmFPANameFromRule
     277    newRule = psStringCopy(rule);
     278
     279    if (strstr(newRule, "{OUTPUT}") != NULL) {
     280        char *name = psMetadataLookupStr(NULL, file->names, "OUTPUT");
     281        if (name) {
     282            psStringSubstitute(&newRule, name, "{OUTPUT}");
     283        }
     284    }
     285
     286    psString newName = pmFPANameFromRule(newRule, file->fpa, view); // New name, to be returned
     287    psFree(newRule);
     288
    275289    return newName;
    276290}
     
    346360        status = pmChipCopyStructure (outChip, inChip, xBin, yBin);
    347361        return status;
    348     } 
     362    }
    349363    if (view->cell >= inChip->cells->n) {
    350364        psError(PS_ERR_IO, true, "Requested cell == %d>= inChip->cells->n == %ld",
     
    410424    switch (type) {
    411425      case PM_FPA_FILE_SX:
    412         return ("SX");
     426        return ("SX");
    413427      case PM_FPA_FILE_OBJ:
    414         return ("OBJ");
     428        return ("OBJ");
    415429      case PM_FPA_FILE_CMP:
    416         return ("CMP");
     430        return ("CMP");
    417431      case PM_FPA_FILE_CMF:
    418         return ("CMF");
     432        return ("CMF");
    419433      case PM_FPA_FILE_RAW:
    420         return ("RAW");
     434        return ("RAW");
    421435      case PM_FPA_FILE_IMAGE:
    422         return ("IMAGE");
     436        return ("IMAGE");
    423437      case PM_FPA_FILE_PSF:
    424         return ("PSF");
     438        return ("PSF");
    425439      case PM_FPA_FILE_JPEG:
    426         return ("JPEG");
     440        return ("JPEG");
    427441      case PM_FPA_FILE_KAPA:
    428         return ("KAPA");
     442        return ("KAPA");
    429443      case PM_FPA_FILE_MASK:
    430         return ("MASK");
     444        return ("MASK");
    431445      case PM_FPA_FILE_WEIGHT:
    432         return ("WEIGHT");
     446        return ("WEIGHT");
    433447      case PM_FPA_FILE_FRINGE:
    434         return ("FRINGE");
     448        return ("FRINGE");
    435449      case PM_FPA_FILE_HEADER:
    436         return ("HEADER");
     450        return ("HEADER");
    437451      default:
    438         return ("NONE");
     452        return ("NONE");
    439453    }
    440454    return ("NONE");
  • trunk/psModules/src/camera/pmFPAfile.h

    r13523 r13810  
    44 * @author EAM, IfA
    55 *
    6  * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2007-05-26 02:50:36 $
     6 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2007-06-14 02:03:29 $
    88 * Copyright 2004-2005 Institute for Astronomy, University of Hawaii
    99 */
     
    5353typedef struct
    5454{
    55     pmFPAfileMode mode;                 // is this file read, written, or only used internally?
    56     pmFPAfileType type;                 // what type of data is read from / written to disk?
    57     pmFPAfileState state;               // have we opened the file, etc?
     55    pmFPAfileMode mode;                 // is this file read, written, or only used internally?
     56    pmFPAfileType type;                 // what type of data is read from / written to disk?
     57    pmFPAfileState state;               // have we opened the file, etc?
    5858
    59     pmFPALevel fileLevel;               // what level in the FPA hierarchy represents a unique file?
    60     pmFPALevel dataLevel;               // at what level do we read/write the data segment? (request by user)
    61     pmFPALevel freeLevel;               // at what level do we free the data segment? (set by program)
     59    pmFPALevel fileLevel;               // what level in the FPA hierarchy represents a unique file?
     60    pmFPALevel dataLevel;               // at what level do we read/write the data segment? (request by user)
     61    pmFPALevel freeLevel;               // at what level do we free the data segment? (set by program)
    6262    pmFPALevel mosaicLevel;             // at what level is the mosaic?
    6363
    64     pmFPA *fpa;                         // for I/O files, we carry a pointer to the complete fpa
    65     psFits *fits;                       // for I/O files of fits type (IMAGE, CMP, CMF), we carry a file handle
     64    pmFPA *fpa;                         // for I/O files, we carry a pointer to the complete fpa
     65    psFits *fits;                       // for I/O files of fits type (IMAGE, CMP, CMF), we carry a file handle
    6666
    67     bool phu;                           // have we written a PHU for this file?
    68     psMetadata *header;                 // pointer (view) to the current hdu header
     67    bool phu;                           // have we written a PHU for this file?
     68    psMetadata *header;                 // pointer (view) to the current hdu header
    6969
    70     pmReadout *readout;                 // for internal files, we only carry a single readout
     70    pmReadout *readout;                 // for internal files, we only carry a single readout
    7171
    72     psMetadata *names;                  // filenames supplied by the cmdline or detdb are saved here
     72    psMetadata *names;                  // filenames supplied by the cmdline or detdb are saved here
    7373
    74     char *filerule;                     // rule for constructing a filename when needed
    75     char *filesrc;                      // rule to find file in pmFPAfile->names list
     74    char *filerule;                     // rule for constructing a filename when needed
     75    char *filesrc;                      // rule to find file in pmFPAfile->names list
    7676
    77     char *name;                         // the name of the rule (useful for debugging / tracing)
    78     char *filename;                     // the current name of an active file
    79     char *extname;                      // the current name of an active file extension
     77    char *name;                         // the name of the rule (useful for debugging / tracing)
     78    char *filename;                     // the current name of an active file
     79    char *extname;                      // the current name of an active file extension
    8080
    8181    pmDetrendSelectResults *detrend;    // Detrend information, from pmDetrendSelect
     
    110110
    111111// convert the rule to a name based on the current view
     112psString pmFPANameFromRule(const char *rule, const pmFPA *fpa, const pmFPAview *view);
     113
     114// convert the rule to a name based on the current view
    112115psString pmFPAfileNameFromRule(const char *rule, const pmFPAfile *file, const pmFPAview *view);
    113116
  • trunk/psModules/src/config/pmConfig.c

    r13704 r13810  
    44 *  @author EAM (IfA)
    55 *
    6  *  @version $Revision: 1.95 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2007-06-08 00:31:50 $
     6 *  @version $Revision: 1.96 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2007-06-14 02:03:29 $
    88 *
    99 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    293293}
    294294
     295// Read the calibrations for a camera
     296static bool cameraReadCalibrations(psMetadata *camera, // Camera for which to read the formats
     297                                   const char *name // Name of the camera, for error messages
     298    )
     299{
     300    assert(camera);
     301    assert(name);
     302
     303    psMetadataItem *darkNorm = psMetadataLookup(camera, "DARK.NORM"); // The dark normalisation calibration
     304    if (darkNorm) {
     305        if (darkNorm->type == PS_DATA_STRING) {
     306            const char *darkNormName = darkNorm->data.str; // The file name
     307            psTrace("config", 2, "Reading %s dark normalisation: %s\n", name, darkNormName);
     308            psMetadata *new = NULL;         // New metadata
     309            if (!pmConfigFileRead(&new, darkNormName, "Dark normalisation")) {
     310                psError(PM_ERR_CONFIG, false, "Trouble reading reading %s dark normalisation %s --- "
     311                        "ignored.\n", name, darkNormName);
     312                psFree(new);
     313                return false;
     314            }
     315
     316            // Muck around under the hood to replace the filename with the metadata;
     317            // don't try this at home, kids
     318            darkNorm->type = PS_DATA_METADATA;
     319            psFree(darkNorm->data.str);
     320            darkNorm->data.md = new;
     321        } else if (darkNorm->type != PS_DATA_METADATA) {
     322            psWarning("DARK.NORM in camera %s is not of type STR or METADATA (%x)", name, darkNorm->type);
     323        }
     324    } else {
     325        // Add a dummy entry
     326        psPolynomial1D *poly = psPolynomial1DAlloc(1, PS_POLYNOMIAL_ORD); // Dummy polynomial
     327        poly->coeff[0] = 0.0;
     328        poly->coeff[1] = 1.0;
     329        psMetadata *polyMD = psMetadataAlloc(); // Container for the polynomial
     330        (void)psPolynomial1DtoMetadata(polyMD, poly, "_DEFAULT"); // Metadata to insert
     331        psFree(poly);
     332        psMetadataAddMetadata(camera, PS_LIST_TAIL, "DARK.NORM", 0, "Dark normalisation polynomial",
     333                              polyMD);
     334        psMetadataAddStr(camera, PS_LIST_TAIL, "DARK.NORM.KEY", 0, "Key for dark normalisation", "_DEFAULT");
     335        psFree(polyMD);
     336    }
     337
     338    return true;
     339}
    295340
    296341pmConfig *pmConfigRead(int *argc, char **argv, const char *defaultRecipe)
     
    530575            }
    531576
     577            // Read in any camera-specific calibrations
     578            if (!cameraReadCalibrations(config->camera, cameraFile)) {
     579                psError(PS_ERR_UNKNOWN, false,
     580                        "Unable to read calibrations within camera configuration %s.\n",
     581                        cameraFile);
     582                psFree(config);
     583                return NULL;
     584            }
     585
    532586            psMetadataAddMetadata(cameras, PS_LIST_HEAD, cameraFile, PS_META_REPLACE,
    533587                                  "Camera specified on command line", config->camera);
  • 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        }
  • trunk/psModules/src/detrend/pmBias.h

    r12696 r13810  
    55 * @author Paul Price, IfA
    66 *
    7  * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2007-03-30 21:12:56 $
     7 * @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2007-06-14 02:03:29 $
    99 * Copyright 2004--2006 Institute for Astronomy, University of Hawaii
    1010 */
     
    5757bool pmBiasSubtract(pmReadout *in,      ///< Input readout, to be overscan/bias/dark corrected
    5858                    pmOverscanOptions *overscanOpts, ///< Options for overscan subtraction, or NULL
    59                     const pmReadout *bias, ///< Bias image to subtract, or NULL
    60                     const pmReadout *dark ///< Dark image to scale and subtract, or NULL
     59                    const pmReadout *bias, ///< Bias to subtract, or NULL
     60                    const pmReadout *dark, ///< Dark to scale and subtract, or NULL
     61                    const pmFPAview *view ///< View for readout of interest
    6162                   );
    6263
Note: See TracChangeset for help on using the changeset viewer.