Changeset 9618
- Timestamp:
- Oct 17, 2006, 2:47:15 PM (20 years ago)
- Location:
- trunk/psModules/src/detrend
- Files:
-
- 2 edited
-
pmShutterCorrection.c (modified) (5 diffs)
-
pmShutterCorrection.h (modified) (1 diff)
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 image6 7 * the measurement could be performed on any focal-plane unit at a time. for8 * GPC, the obvious scale is to measure the effect on the entire focal plane at9 * once, with a single reference point in the field. this is a little more10 * complex than just measuring the effect for a single 2D image array. the11 * reference point and the detailed analysis points need to be defined for the12 * entire hierarchy rather than just as coordinate pairs or regions. a13 * pmFPAview would be a natural element with which to define these points, but14 * at the moment, the pmFPAview structure defines a band in the CCD, not a15 * coordinate. An option is to instead specify the reference locations as a16 * pmFPAview coupled with a psRegion, though we need to be careful not to17 * 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 reference21 * coordinate, and F(k;T) is the measured number of counts at the point of22 * interest in this image. given a collection of f(k;T) values, we need to23 * determine the model f(k;T) = A(k) (T + dTk) / (T + dTo) where dTk is the shutter24 * error at the given position, dTo is the shutter error at the reference25 * position, and A(k) is the scaling factor for the given position.26 27 - load the configuration information28 - load the input file information, build pmFPAfile's for all inputs29 30 - determine the reference point and detailed analysis regions from the config information31 - for each image32 -- measure the reference point counts33 - for each analysis region:34 -- measure shutter parameters (dTo, dTk, A):35 --- for each image:36 ---- measure counts at the region37 ---- divide by the reference counts38 --- linear extrapolation to find f(inf) = A(k)39 --- linear extrapolation to find f(0) = A(k) dTk / dTo40 --- linear interpolation to find coordinate where f(dTo) = A (1 + dTk/dTo) / 241 --- 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 pixel44 -- divide by the reference counts45 -- 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 above47 -- save dTk, A(k) in output image pixels48 -- apply dTk, A(k) to measure residual images49 -- generate residual FITS/JPEG images50 51 */52 53 1 #if HAVE_CONFIG_H 54 2 #include <config.h> … … 63 11 #include "pmShutterCorrection.h" 64 12 #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 65 55 66 56 static void pmShutterCorrectionFree(pmShutterCorrection *pars) … … 360 350 #define MEASURE_SAMPLES 4 361 351 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 ) 352 psImage *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) 373 355 { 374 356 PS_ASSERT_VECTOR_NON_NULL(exptimes, NULL); … … 376 358 PS_ASSERT_ARRAY_NON_NULL(images, NULL); 377 359 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); 380 361 } 381 362 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); 384 364 } 385 365 long num = images->n; // Number of images … … 576 556 577 557 578 bool pmShutterCorrectionApply(pmReadout *readout, // Readout to which to apply shutter correction 579 const pmReadout *shutter // Shutter correction readout 580 ) 558 bool pmShutterCorrectionApply(pmReadout *readout, const pmReadout *shutter) 581 559 { 582 560 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) 55 59 56 60 #ifndef PM_SHUTTER_CORRECTION_H 57 61 #define PM_SHUTTER_CORRECTION_H 58 62 59 #include "pslib.h"63 #include <pslib.h> 60 64 61 // Shutter correction parameters, applicable for a single pixel65 /// Shutter correction parameters, applicable for a single pixel 62 66 typedef struct 63 67 { 64 double scale; // The normalisation for an exposure, A(k)65 double offset; // The time offset, dTk66 double offref; // The reference time offset, dTo68 double scale; ///< The normalisation for an exposure, A(k) 69 double offset; ///< The time offset, dTk 70 double offref; ///< The reference time offset, dTo 67 71 } 68 72 pmShutterCorrection; 69 73 70 // Allocator74 /// Allocator for shutter correction parameters 71 75 pmShutterCorrection *pmShutterCorrectionAlloc(); 72 76 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. 81 pmShutterCorrection *pmShutterCorrectionGuess(const psVector *exptime, ///< Exposure times for each exposure 82 const psVector *counts ///< Counts for each exposure 78 83 ); 79 84 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. 89 pmShutterCorrection *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 89 97 ); 90 98 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. 104 pmShutterCorrection *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 96 108 ); 97 109 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. 116 psImage *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 109 126 ); 110 127 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. 131 bool pmShutterCorrectionApply(pmReadout *readout, ///< Readout to which to apply shutter correction 132 const pmReadout *shutter ///< Shutter correction readout, with dT for each pixel 114 133 ); 115 134
Note:
See TracChangeset
for help on using the changeset viewer.
