IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 9618


Ignore:
Timestamp:
Oct 17, 2006, 2:47:15 PM (20 years ago)
Author:
Paul Price
Message:

Documenting pmShutterCorrection.[ch]

Location:
trunk/psModules/src/detrend
Files:
2 edited

Legend:

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

    r9539 r9618  
    1 /*
    2  * measure shutter correction:
    3  
    4  * input  : collection of shutter correction exposures (pre-processed)
    5  * output : a shutter correction image
    6  
    7  * the measurement could be performed on any focal-plane unit at a time. for
    8  * GPC, the obvious scale is to measure the effect on the entire focal plane at
    9  * once, with a single reference point in the field.  this is a little more
    10  * complex than just measuring the effect for a single 2D image array.  the
    11  * reference point and the detailed analysis points need to be defined for the
    12  * entire hierarchy rather than just as coordinate pairs or regions.  a
    13  * pmFPAview would be a natural element with which to define these points, but
    14  * at the moment, the pmFPAview structure defines a band in the CCD, not a
    15  * coordinate.  An option is to instead specify the reference locations as a
    16  * pmFPAview coupled with a psRegion, though we need to be careful not to
    17  * over-specify the pixels (ie, conflict between pmFPAview and psRegion).
    18  
    19  * at each point in an image with exposure time T, we measure f(k;T) = F(k;T) /
    20  * F(0;T) where k is the coordinate of the point of interest, 0 is the reference
    21  * coordinate, and F(k;T) is the measured number of counts at the point of
    22  * interest in this image.  given a collection of f(k;T) values, we need to
    23  * determine the model f(k;T) = A(k) (T + dTk) / (T + dTo) where dTk is the shutter
    24  * error at the given position, dTo is the shutter error at the reference
    25  * position, and A(k) is the scaling factor for the given position.
    26  
    27  - load the configuration information
    28  - load the input file information, build pmFPAfile's for all inputs
    29  
    30  - determine the reference point and detailed analysis regions from the config information
    31  - for each image
    32  -- measure the reference point counts
    33  - for each analysis region:
    34  -- measure shutter parameters (dTo, dTk, A):
    35  --- for each image:
    36  ---- measure counts at the region
    37  ---- divide by the reference counts
    38  --- linear extrapolation to find f(inf) = A(k)
    39  --- linear extrapolation to find f(0) = A(k) dTk / dTo
    40  --- linear interpolation to find coordinate where f(dTo) = A (1 + dTk/dTo) / 2
    41  --- non-linear fit of T, f(T) to f(k;T) = A(k) (T + dTk) / (T + dTo)
    42  - use the collection of dTo values to choose a best value for dTo (median)
    43  - for each image pixel
    44  -- divide by the reference counts
    45  -- generate the vectors T, f(T)
    46  -- linear fit of T, f(T) to f(k;T) = A(k) (T + dTk) / (T + dTo) using dTo above
    47  -- save dTk, A(k) in output image pixels
    48  -- apply dTk, A(k) to measure residual images
    49  -- generate residual FITS/JPEG images
    50  
    51 */
    52 
    531#if HAVE_CONFIG_H
    542#include <config.h>
     
    6311#include "pmShutterCorrection.h"
    6412#include "psVectorBracket.h"
     13
     14/// Measure shutter correction:
     15///
     16/// input  : collection of shutter correction exposures (pre-processed)
     17/// output : a shutter correction image
     18///
     19/// The measurement could be performed on any focal-plane unit at a time. for GPC, the obvious scale is to
     20/// measure the effect on the entire focal plane at once, with a single reference point in the field.  this is
     21/// a little more complex than just measuring the effect for a single 2D image array.  the reference point and
     22/// the detailed analysis points need to be defined for the entire hierarchy rather than just as coordinate
     23/// pairs or regions.  a pmFPAview would be a natural element with which to define these points, but at the
     24/// moment, the pmFPAview structure defines a band in the CCD, not a coordinate.  An option is to instead
     25/// specify the reference locations as a pmFPAview coupled with a psRegion, though we need to be careful not
     26/// to over-specify the pixels (ie, conflict between pmFPAview and psRegion).
     27///
     28/// At each point in an image with exposure time T, we measure f(k;T) = F(k;T) / F(0;T) where k is the
     29/// coordinate of the point of interest, 0 is the reference coordinate, and F(k;T) is the measured number of
     30/// counts at the point of interest in this image.  given a collection of f(k;T) values, we need to determine
     31/// the model f(k;T) = A(k) (T + dTk) / (T + dTo) where dTk is the shutter error at the given position, dTo is
     32/// the shutter error at the reference position, and A(k) is the scaling factor for the given position.
     33///
     34/// The process for generating a shutter correction is as follows:
     35/// - for each image
     36/// -- measure the reference point counts
     37/// - for each analysis region:
     38/// -- measure shutter parameters (dTo, dTk, A):
     39/// --- for each image:
     40/// ---- measure counts at the region
     41/// ---- divide by the reference counts
     42/// --- linear extrapolation to find f(inf) = A(k)
     43/// --- linear extrapolation to find f(0) = A(k) dTk / dTo
     44/// --- linear interpolation to find coordinate where f(dTo) = A (1 + dTk/dTo) / 2
     45/// --- non-linear fit of T, f(T) to f(k;T) = A(k) (T + dTk) / (T + dTo)
     46/// - use the collection of dTo values to choose a best value for dTo (median)
     47/// - for each image pixel
     48/// -- divide by the reference counts
     49/// -- generate the vectors T, f(T)
     50/// -- linear fit of T, f(T) to f(k;T) = A(k) (T + dTk) / (T + dTo) using dTo above
     51/// -- save dTk, A(k) in output image pixels
     52/// -- apply dTk, A(k) to measure residual images
     53/// -- generate residual FITS/JPEG images
     54
    6555
    6656static void pmShutterCorrectionFree(pmShutterCorrection *pars)
     
    360350#define MEASURE_SAMPLES 4
    361351
    362 psImage *pmShutterCorrectionMeasure(const psVector *exptimes, // Exposure times
    363                                     const psArray *images, // Input images
    364                                     const psArray *weights, // Weight images
    365                                     const psArray *masks, // Mask images
    366                                     unsigned int size, // Size of samples
    367                                     psStatsOptions meanStat, // Statistic to use for mean
    368                                     psStatsOptions stdevStat, // Statistic to use for stdev
    369                                     int nIter, // Number of iterations per pixel
    370                                     float rej, // Rejection limit
    371                                     psMaskType maskVal // Mask value
    372                                    )
     352psImage *pmShutterCorrectionMeasure(const psVector *exptimes, const psArray *images, const psArray *weights,
     353                                    const psArray *masks, unsigned int size, psStatsOptions meanStat,
     354                                    psStatsOptions stdevStat, int nIter, float rej, psMaskType maskVal)
    373355{
    374356    PS_ASSERT_VECTOR_NON_NULL(exptimes, NULL);
     
    376358    PS_ASSERT_ARRAY_NON_NULL(images, NULL);
    377359    if (masks) {
    378         // XXX ASSERT not defined
    379         // PS_ASSERT_ARRAYS_SIZE_EQUAL(images, masks, NULL);
     360        PS_ASSERT_ARRAYS_SIZE_EQUAL(images, masks, NULL);
    380361    }
    381362    if (weights) {
    382         // XXX ASSERT not defined
    383         // PS_ASSERT_ARRAYS_SIZE_EQUAL(images, weights, NULL);
     363        PS_ASSERT_ARRAYS_SIZE_EQUAL(images, weights, NULL);
    384364    }
    385365    long num = images->n;               // Number of images
     
    576556
    577557
    578 bool pmShutterCorrectionApply(pmReadout *readout, // Readout to which to apply shutter correction
    579                               const pmReadout *shutter // Shutter correction readout
    580                              )
     558bool pmShutterCorrectionApply(pmReadout *readout, const pmReadout *shutter)
    581559{
    582560    PS_ASSERT_PTR_NON_NULL(readout, false);
  • trunk/psModules/src/detrend/pmShutterCorrection.h

    r9340 r9618  
    1 /** @file  pmShutterCorrection.h
    2  *
    3  *  @brief Functions to build and apply a shutter exposure-time correction.
    4  *
    5  *  A mechanical shutter may not yield uniform exposure times as a function of
    6  *  position on the detector.  The typical error consists of a constant
    7  *  exposure-time offset relative to the requested value, ie exposure time is
    8  *  T_o + dT(x,y).  The exposure error, dT, may be measured with the following
    9  *  scheme.  Obtain a set of exposures with different exposures times taken of
    10  *  the same flat-field source; the source must be spatially stable between the
    11  *  exposures, but need not have a stable amplitude.  For an illuminating flux
    12  *  of intensity F(x,y) = F_o f(x,y), the signal recorded by any pixel in the
    13  *  detector is given by: S(t,x,y) = F_o(t) f(x,y) (T_o + dT(x,y)) where F_o is
    14  *  the F_o(t) is the (variable) overall intensity of the illuminating source
    15  *  and f(x,y) is the spatial illumination patter times the flat-field response.
    16  *  Choose a reference location in the image (eg, the detector center) and
    17  *  divide by the value of that region (ie, mean or median):
    18  
    19  *  s(t,x,y) = S(t,x,y) / S(t,0,0)
    20  *  s(t,x,y) = F_o(t) f(x,y) (T_o + dT(x,y)) / F_o(t) f(0,0) (T_o + dT(0,0))
    21  *  s(t,x,y) = f(x,y) (T_o + dT(x,y)) / f(0,0) (T_o + dT(0,0))
    22  
    23  * we can absorb the term f(0,0) into f(x,y) as we have no motivation for the
    24  * scale of f(x,y).  For any single pixel, over the set of exposures, we thus
    25  * need to solve for dT(x,y), dT(0,0), and f'(x,y) in the equation:
    26  * s(t,x,y) = f'(x,y) (T_o + dT(x,y)) / (T_o + dT(0,0))
    27  
    28  * we avoid directly fitting these values as the process would be a non-linear
    29  * least-squares problem for every pixel in the image, and thus very time
    30  * consuming.  There are linear options which may be used instead.
    31  * First, as T_o goes to a large value, s() approaches the value of f'(x,y).
    32  * Next, as T_o goes to a very small value, s() approaches the value of
    33  * f'(x,y)*dT(x,y)/dT(0,0).  Finally, when s() has the value of
    34  * f'(x,y)*(1 + dT(x,y)/dT(0,0))/2, T_o has the value of dT(0,0).  with data
    35  * points covering a reasonable dynamic range, we can solve for these three
    36  * values by interpolation and/or extrapolation.
    37  
    38  * To take the strategy one step further, we could use the above recipe to
    39  * obtain a guess for the three parameters and then apply non-linear fitting to
    40  * solve more accurately for the parameters.  If we limit this operation to a
    41  * handful of positions in the image (user defined, but the obvious choice would
    42  * be positions near the center, edges, and corners), then we may determine a
    43  * good value for dT(0,0).  Since there is only one dT(0,0) for the image, we
    44  * can apply the resulting measurement to the rest of the pixels in the image.
    45  * If dT(0,0) is not a free parameter, then the fitting process is linear in
    46  * terms of dT(x,y) and f'(x,y)
    47  
    48  *  @author Eugene Magnier, IfA
    49  *
    50  *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    51  *  @date $Date: 2006-10-06 03:33:49 $
    52  *
    53  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    54  */
     1/// @file pmShutterCorrection.h
     2///
     3/// @brief Functions to build and apply a shutter exposure-time correction.
     4///
     5/// @ingroup Detrend
     6///
     7/// @author Eugene Magnier, IfA
     8/// @author Paul Price, IfA
     9///
     10/// @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     11/// @date $Date: 2006-10-18 00:47:15 $
     12///
     13/// Copyright 2006 Institute for Astronomy, University of Hawaii
     14///
     15
     16
     17/// A mechanical shutter may not yield uniform exposure times as a function of
     18/// position on the detector.  The typical error consists of a constant
     19/// exposure-time offset relative to the requested value, ie exposure time is
     20/// T_o + dT(x,y).  The exposure error, dT, may be measured with the following
     21/// scheme.  Obtain a set of exposures with different exposures times taken of
     22/// the same flat-field source; the source must be spatially stable between the
     23/// exposures, but need not have a stable amplitude.  For an illuminating flux
     24/// of intensity F(x,y) = F_o f(x,y), the signal recorded by any pixel in the
     25/// detector is given by: S(t,x,y) = F_o(t) f(x,y) (T_o + dT(x,y)) where F_o is
     26/// the F_o(t) is the (variable) overall intensity of the illuminating source
     27/// and f(x,y) is the spatial illumination patter times the flat-field response.
     28/// Choose a reference location in the image (eg, the detector center) and
     29/// divide by the value of that region (ie, mean or median):
     30///
     31/// s(t,x,y) = S(t,x,y) / S(t,0,0)
     32/// s(t,x,y) = F_o(t) f(x,y) (T_o + dT(x,y)) / F_o(t) f(0,0) (T_o + dT(0,0))
     33/// s(t,x,y) = f(x,y) (T_o + dT(x,y)) / f(0,0) (T_o + dT(0,0))
     34///
     35/// we can absorb the term f(0,0) into f(x,y) as we have no motivation for the
     36/// scale of f(x,y).  For any single pixel, over the set of exposures, we thus
     37/// need to solve for dT(x,y), dT(0,0), and f'(x,y) in the equation:
     38/// s(t,x,y) = f'(x,y) (T_o + dT(x,y)) / (T_o + dT(0,0))
     39///
     40/// we avoid directly fitting these values as the process would be a non-linear
     41/// least-squares problem for every pixel in the image, and thus very time
     42/// consuming.  There are linear options which may be used instead.
     43/// First, as T_o goes to a large value, s() approaches the value of f'(x,y).
     44/// Next, as T_o goes to a very small value, s() approaches the value of
     45/// f'(x,y)*dT(x,y)/dT(0,0).  Finally, when s() has the value of
     46/// f'(x,y)*(1 + dT(x,y)/dT(0,0))/2, T_o has the value of dT(0,0).  with data
     47/// points covering a reasonable dynamic range, we can solve for these three
     48/// values by interpolation and/or extrapolation.
     49///
     50/// To take the strategy one step further, we could use the above recipe to
     51/// obtain a guess for the three parameters and then apply non-linear fitting to
     52/// solve more accurately for the parameters.  If we limit this operation to a
     53/// handful of positions in the image (user defined, but the obvious choice would
     54/// be positions near the center, edges, and corners), then we may determine a
     55/// good value for dT(0,0).  Since there is only one dT(0,0) for the image, we
     56/// can apply the resulting measurement to the rest of the pixels in the image.
     57/// If dT(0,0) is not a free parameter, then the fitting process is linear in
     58/// terms of dT(x,y) and f'(x,y)
    5559
    5660#ifndef PM_SHUTTER_CORRECTION_H
    5761#define PM_SHUTTER_CORRECTION_H
    5862
    59 #include "pslib.h"
     63#include <pslib.h>
    6064
    61 // Shutter correction parameters, applicable for a single pixel
     65/// Shutter correction parameters, applicable for a single pixel
    6266typedef struct
    6367{
    64     double scale;                       // The normalisation for an exposure, A(k)
    65     double offset;                      // The time offset, dTk
    66     double offref;                      // The reference time offset, dTo
     68    double scale;                       ///< The normalisation for an exposure, A(k)
     69    double offset;                      ///< The time offset, dTk
     70    double offref;                      ///< The reference time offset, dTo
    6771}
    6872pmShutterCorrection;
    6973
    70 // Allocator
     74/// Allocator for shutter correction parameters
    7175pmShutterCorrection *pmShutterCorrectionAlloc();
    7276
    73 // Guess a shutter correction, based on plot of counts vs exposure time.
    74 // Used before doing the full non-linear fit, to get parameters close to the true.
    75 // Assumes exptime vector is sorted (ascending order; longest is last) prior to input.
    76 pmShutterCorrection *pmShutterCorrectionGuess(const psVector *exptime, // Exposure times for each exposure
    77         const psVector *counts // Counts for each exposure
     77/// Guess a shutter correction, based on plot of counts vs exposure time
     78///
     79/// This function is used before doing the full non-linear fit, to get parameters close to the true.  Assumes
     80/// exptime vector is sorted (ascending order; longest is last) prior to input.
     81pmShutterCorrection *pmShutterCorrectionGuess(const psVector *exptime, ///< Exposure times for each exposure
     82        const psVector *counts ///< Counts for each exposure
    7883                                             );
    7984
    80 // Generate shutter correction based on a linear fit
    81 pmShutterCorrection *pmShutterCorrectionLinFit(const psVector *exptime, // Exposure times for each exposure
    82         const psVector *counts, // Counts for each exposure
    83         const psVector *cntError, // Error in the counts, for each exp.
    84         const psVector *mask, // Mask for each exposure
    85         float offref, // Reference time offset
    86         int nIter, // Number of iterations
    87         float rej, // Rejection threshold (sigma)
    88         psMaskType maskVal // Mask value
     85/// Generate shutter correction based on a linear fit
     86///
     87/// Performs a linear fit to counts as a function of exposure time, with the reference time offset fixed (so
     88/// that the system is linear).  Performs iterative clipping, if nIter > 1.
     89pmShutterCorrection *pmShutterCorrectionLinFit(const psVector *exptime, ///< Exposure times for each exposure
     90        const psVector *counts, ///< Counts for each exposure
     91        const psVector *cntError, ///< Error in the counts
     92        const psVector *mask, ///< Mask for each exposure
     93        float offref, ///< Reference time offset
     94        int nIter, ///< Number of iterations
     95        float rej, ///< Rejection threshold (sigma)
     96        psMaskType maskVal ///< Mask value
    8997                                              );
    9098
    91 // Generate shutter correction based on a full non-linear fit
    92 pmShutterCorrection *pmShutterCorrectionFullFit(const psVector *exptime, // Exposure times for each exposure
    93         const psVector *counts, // Counts for each exposure
    94         const psVector *cntError, // Error in the counts, for each exp
    95         const pmShutterCorrection *guess // Initial guess
     99/// Generate shutter correction based on a full non-linear fit
     100///
     101/// Performs a full non-linear fit to counts as a function of exposure time.  The main purpose is to solve for
     102/// the reference time offset, so that future fits may be performed using linear fitting with the reference
     103/// time offset fixed.
     104pmShutterCorrection *pmShutterCorrectionFullFit(const psVector *exptime, ///< Exposure times for each exposure
     105        const psVector *counts, ///< Counts for each exposure
     106        const psVector *cntError, ///< Error in the counts
     107        const pmShutterCorrection *guess ///< Initial guess
    96108                                               );
    97109
    98 // Measure a shutter correction image from an array of images
    99 psImage *pmShutterCorrectionMeasure(const psVector *exptimes, // Exposure times
    100                                     const psArray *images, // Input images
    101                                     const psArray *weights, // Weight images
    102                                     const psArray *masks, // Mask images
    103                                     unsigned int size, // Size of samples
    104                                     psStatsOptions meanStat, // Statistic to use for mean
    105                                     psStatsOptions stdevStat, // Statistic to use for stdev
    106                                     int nIter, // Number of iterations
    107                                     float rej, // Rejection threshold (sigma)
    108                                     psMaskType maskVal // Mask value
     110/// Measure a shutter correction image from an array of images
     111///
     112/// Given an array of images with known exposure times, this function measures the shutter correction (our
     113/// principal concern is for the time offset, rather than the normalisation) by measuring the reference time
     114/// offset using the full non-linear fit for a small number of representative regions (middle and corners),
     115/// and then using that to perform a linear fit to each pixel.
     116psImage *pmShutterCorrectionMeasure(const psVector *exptimes, ///< Exposure times
     117                                    const psArray *images, ///< Input images
     118                                    const psArray *weights, ///< Weight images
     119                                    const psArray *masks, ///< Mask images
     120                                    unsigned int size, ///< Size of samples for statistics for non-linear fit
     121                                    psStatsOptions meanStat, ///< Statistic to use for mean
     122                                    psStatsOptions stdevStat, ///< Statistic to use for stdev
     123                                    int nIter, ///< Number of iterations
     124                                    float rej, ///< Rejection threshold (sigma)
     125                                    psMaskType maskVal ///< Mask value
    109126                                   );
    110127
    111 // Apply a shutter correction
    112 bool pmShutterCorrectionApply(pmReadout *readout, // Readout to which to apply shutter correction
    113                               const pmReadout *shutter // Shutter correction readout
     128/// Apply a shutter correction
     129///
     130/// Given a shutter correction (with dT for each pixel), applies this correction to an input image.
     131bool pmShutterCorrectionApply(pmReadout *readout, ///< Readout to which to apply shutter correction
     132                              const pmReadout *shutter ///< Shutter correction readout, with dT for each pixel
    114133                             );
    115134
Note: See TracChangeset for help on using the changeset viewer.