00001 #ifndef CUBE_CONSTRUCT_H 00002 #define CUBE_CONSTRUCT_H 00003 /******************************************************************************* 00004 * E.S.O. - VLT project 00005 * 00006 * "@(#) $Id: cube_construct.h,v 1.6 2005/04/19 11:39:52 amodigli Exp $" 00007 * 00008 * who when what 00009 * -------- -------- ---------------------------------------------- 00010 * schreib 06/10/00 created 00011 */ 00012 00013 /************************************************************************ 00014 * cube_construct.h 00015 * routines needed to construct a 3D-data cube 00016 *---------------------------------------------------------------------- 00017 */ 00018 00019 /* 00020 * header files 00021 */ 00022 00023 /* 00024 #include <stdio.h> 00025 #include <inttypes.h> 00026 #include <string.h> 00027 #include <cpl.h> 00028 #include <math.h> 00029 */ 00030 00031 #include "cube_ops.h" 00032 #include <qfits.h> 00033 /* 00034 #include "recipes.h" 00035 #include "eclipse.h" 00036 #include "wave_calibration.h" 00037 */ 00038 00039 00040 /* 00041 * function prototypes 00042 */ 00043 00044 /*---------------------------------------------------------------------------- 00045 Function : convolveNSImageByGauss() 00046 In : lineImage: North-south-test image 00047 hw: kernel half width of the gaussian 00048 response function 00049 Out : north-south-test image convolved with a gaussian 00050 Job : convolves a north-south-test image with a gaussian 00051 with user given integer half width by using the eclipse 00052 routine function1d_filter_lowpass(). 00053 ---------------------------------------------------------------------------*/ 00054 00055 /* <python> */ 00056 OneImage * convolveNSImageByGauss( OneImage * lineImage, 00057 int hw ) ; 00058 /* </python> */ 00059 00060 /*---------------------------------------------------------------------------- 00061 Function : north_south_test() 00062 In : ns_image: north-south image 00063 n_slitlets: number of slitlets 00064 halfWidth: half width of the box in which the lines 00065 are fit by a gaussian 00066 fwhm: first guess of the full width at half maximum 00067 minDiff: amplitude threshold for Gaussian: 00068 below this intensity the fit will not 00069 be carried through 00070 estimated_dist: estimated average distance of spectra 00071 devtol: maximal pixel deviation of slitlet distances 00072 Out : array of the distances of the slitlets 00073 from each other 00074 Job : determines the distances of the slitlets 00075 ---------------------------------------------------------------------------*/ 00076 /* <python> */ 00077 float * north_south_test( OneImage * ns_image, 00078 int n_slitlets, 00079 int halfWidth, 00080 float fwhm, 00081 float minDiff, 00082 float estimated_dist, 00083 float devtol, 00084 int top, 00085 int bottom ) ; 00086 /* </python> */ 00087 00088 /*---------------------------------------------------------------------------- 00089 Function : makeCube() 00090 In : calibImage: resampled source image 00091 distances: distances of the slitlets from each other 00092 output of function ns_test 00093 correct_diff_dist: dummy array with 32 elements 00094 Out : resulting source data cube 00095 correct_diff_dist: differences of the slitlets from 00096 distance 32 given in the correct 00097 Spiffi sequence. The first slitlet 00098 is the reference, therefore element 00099 23 is set 0. 00100 Job : makes a data cube out of a resampled source image 00101 this SPIFFI specific routine takes into account the 00102 Spiffi slitlet order on the detector. 00103 Also shifts the resulting image rows by one pixel if 00104 necessary according to the distances array gained from 00105 the north-south test routine. 00106 Can do the same with the bad pixel map image to generate a 00107 bad pixel mask cube. 00108 ---------------------------------------------------------------------------*/ 00109 00110 OneCube * makeCube ( OneImage * calibImage, 00111 float * distances, 00112 float * correct_diff_dist ) ; 00113 00114 /*---------------------------------------------------------------------------- 00115 Function : makeCubeSpi() 00116 In : calibImage: resampled source image 00117 slit_edges: absolute beginning and ending positions of 00118 slitlet, output of fitSlits(). 00119 shift: sub_pixel shifts referred to the reference slit 00120 edge 00121 Out : resulting source data cube 00122 shift: sub_pixel shifts referred to the reference slit 00123 edge 00124 Job : makes a data cube out of a resampled source image 00125 this SPIFFI specific routine takes into account the 00126 Spiffi slitlet order on the detector. 00127 This routine takes fitted slitlet positions into account. 00128 Can do the same with the bad pixel map image to generate a 00129 bad pixel mask cube. 00130 ---------------------------------------------------------------------------*/ 00131 00132 /* <python> */ 00133 OneCube * makeCubeSpi ( OneImage * calibImage, 00134 float ** slit_edges, 00135 float * shift ) ; 00136 /* </python> */ 00137 00138 /*---------------------------------------------------------------------------- 00139 Function : makeCubeDist() 00140 In : calibImage: resampled source image 00141 firstCol: floating point value of the first column of 00142 the first slitlet in the resampled image, 00143 determined "by hand" 00144 distances: distances of the slitlets from each other 00145 output of function ns_test 00146 shift: dummy array with 32 elements 00147 Out : resulting source data cube 00148 shift: differences of the slitlets from 00149 distance 32 given in the correct 00150 Spiffi row sequence. The first slitlet 00151 is the reference, therefore element 00152 23 is set 0. 00153 Job : makes a data cube out of a resampled source image 00154 this SPIFFI specific routine takes into account the 00155 Spiffi slitlet order on the detector. 00156 Also shifts the resulting image rows by one pixel if 00157 necessary according to the distances array gained from 00158 the north-south test routine. 00159 Can do the same with the bad pixel map image to generate a 00160 bad pixel mask cube. 00161 ---------------------------------------------------------------------------*/ 00162 /* <python> */ 00163 OneCube * makeCubeDist ( OneImage * calibImage, 00164 float firstCol, 00165 float * distances, 00166 float * shift ) ; 00167 /* </python> */ 00168 00169 /*---------------------------------------------------------------------------- 00170 Function : make3DCubeDist() 00171 In : calibImage: resampled source image 00172 firstCol: floating point value of the first column of 00173 the first slitlet in the resampled image, 00174 determined "by hand" 00175 distances: distances of the slitlets from each other 00176 output of function ns_test 00177 shift: dummy array with 32 elements 00178 Out : resulting source data cube 00179 shift: differences of the slitlets from 00180 distance 32 given in the correct 00181 Spiffi row sequence. The first slitlet 00182 is the reference, therefore element 00183 23 is set 0. 00184 Job : makes a data cube out of a resampled source image 00185 this 3D specific routine takes into account the 00186 3D slitlet order on the detector. 00187 Also shifts the resulting image rows by one pixel if 00188 necessary according to the distances array gained from 00189 the north-south test routine. 00190 Can do the same with the bad pixel map image to generate a 00191 bad pixel mask cube. 00192 ---------------------------------------------------------------------------*/ 00193 /* <python> */ 00194 OneCube * make3DCubeDist ( OneImage * calibImage, 00195 float firstCol, 00196 float * distances, 00197 float * shift ) ; 00198 /* </python> */ 00199 00200 /*---------------------------------------------------------------------------- 00201 Function : make3DCube() 00202 In : calibImage: resampled source image 00203 kpixshift: integer pixel shifts of the resulting image 00204 plane rows. 00205 kpixfirst: first valid pixel 00206 Out : resulting source data cube 00207 Job : makes a data cube out of a resampled source image 00208 this MPE 3D specific routine takes into account the 00209 3D slitlet order on the detector. 00210 Also shifts the resulting image row by an integer pixel shift if 00211 necessary according to the input kpixshift array 00212 Can do the same with the bad pixel map image to generate a 00213 bad pixel mask cube. 00214 ---------------------------------------------------------------------------*/ 00215 /* <python> */ 00216 OneCube * make3DCube ( OneImage * calibImage, 00217 int * kpixshift, 00218 int kpixfirst ) ; 00219 /* </python> */ 00220 00221 /*---------------------------------------------------------------------------- 00222 Function : determineMaskCube() 00223 In : sourceMaskCube: bad pixel mask cube generated by using 00224 the bad pixel mask frame (0: bad, 1: good) 00225 and going through 00226 the same reduction steps as with the 00227 observation frame. 00228 lowLimit: low limit of pixel value (about -0.7) 00229 highLimit: high limit of bad pixel value (about 0.7) 00230 Out : resulting bad pixel data cube (bad pixels: 0, good pixels: 1). 00231 Job : converts resampled bad pixels to real bad pixels in data cubes. 00232 ---------------------------------------------------------------------------*/ 00233 00234 /* <python> */ 00235 OneCube * determineMaskCube ( OneCube * sourceMaskCube, 00236 float lowLimit, 00237 float highLimit ) ; 00238 /* </python> */ 00239 00240 /*---------------------------------------------------------------------------- 00241 Function : interpolCube() 00242 In : sourceCube: reconstructed source cube from makeCube 00243 without fine tuning of rows 00244 maskCube: bad pixel mask cube, bad pixel are marked 00245 with 0., good and interpolated pixels with 1. 00246 this maskCube is changed within the routine 00247 if a bad pixel was interpolated. 00248 n_neighbors: number of neighbors in one spectral direction 00249 with which the bad pixel will be interpolated (7) 00250 max_radius: maximal pixel radius within an image plane 00251 inside which valid pixels are searched to 00252 be used for interpolation. If there aren't 00253 found 9 good neighboring pixels within this 00254 radius the loop is left. (5) 00255 Out : resulting interpolated data cube. 00256 changed maskCube at the positions of the interpolated pixels 00257 Job : Bad pixel interpolation 3D like (saturated pixels exist): 00258 interpolates the bad pixels of the source cube by 00259 using the nearest neighbors. 00260 first it is checked if the bad pixel is interpolatable: 00261 it is only interpolatable if the number of good pixels 00262 in its spectrum of length 2*n_neighbors+1 exceeds 3 and 00263 if there is at least one good pixel on either side of the 00264 central pixel. 00265 Afterwards good neighboring pixels are searched within the 00266 image plane of the bad pixel by using an increasing pixel radius. 00267 Good pixels mean, the corresponding spectral pixels of the 00268 bad pixel and its spatial neighboring pixel must have 00269 at least 2 valid pixel pairs to be able to be used for 00270 the interpolation. The search is stopped if 9 valid neighboring 00271 pixels are found. 00272 Now normalize the found spectral values, collect the valid pixels 00273 (there must be at least 18) and take the median of the valid 00274 pixels with which the bad pixel is replaced. 00275 ---------------------------------------------------------------------------*/ 00276 00277 /* <python> */ 00278 OneCube * interpolCube ( OneCube * sourceCube, 00279 OneCube * maskCube, 00280 int n_neighbors, /* 7 */ 00281 int max_radius ) ; /* 5 */ 00282 /* </python> */ 00283 00284 /*---------------------------------------------------------------------------- 00285 Function : fineTuneCube() 00286 In : cube: cube, output of makeCube 00287 correct_diff_dist: differences of the slitlets from 00288 distance 32 given in the correct 00289 Spiffi row sequence. The first slitlet 00290 is the reference, therefore element 00291 23 is set 0. 00292 Output of makeCube! 00293 Out : resulting data cube having the exact row positions 00294 Job : fine tunes each row in the right position according 00295 to the distances of the slitlets to each other 00296 (output of the north-south test). 00297 This means that the rows must be realigned by a 00298 fraction of a pixel to accomodate non-integer slit 00299 length. The fractional realignment is done by using 00300 tanh interpolation. 00301 Each row is rescaled so that the total flux is 00302 conserved. 00303 ---------------------------------------------------------------------------*/ 00304 00305 /* <python> */ 00306 OneCube * fineTuneCube( OneCube * cube, 00307 float * correct_diff_dist,int n_order) ; 00308 /* </python> */ 00309 00310 /*---------------------------------------------------------------------------- 00311 Function : fineTuneCubeByFFT() 00312 In : cube: cube, output of makeCube 00313 correct_diff_dist: differences of the slitlets from 00314 distance 32 given in the correct 00315 Spiffi row sequence. The first slitlet 00316 is the reference, therefore element 00317 23 is set 0. 00318 Output of makeCube! 00319 Out : resulting data cube having the exact row positions 00320 Job : fine tunes each row in the right position according 00321 to the distances of the slitlets to each other 00322 (output of the north-south test). 00323 This means that the rows must be realigned by a 00324 fraction of a pixel to accomodate non-integer slit 00325 length. The fractional realignment is done by using 00326 the FFT algorithm four1() of N.R. 00327 ---------------------------------------------------------------------------*/ 00328 00329 /* <python> */ 00330 OneCube * fineTuneCubeByFFT( OneCube * cube, 00331 float * correct_diff_dist ) ; 00332 /* </python> */ 00333 00334 /*---------------------------------------------------------------------------- 00335 Function : fineTuneCubeBySpline() 00336 In : cube: cube, output of makeCube 00337 correct_diff_dist: differences of the slitlets from 00338 distance 32 given in the correct 00339 Spiffi row sequence. The first slitlet 00340 is the reference, therefore element 00341 23 is set 0. 00342 Output of makeCube! 00343 Out : resulting data cube having the exact row positions 00344 Job : fine tunes each row in the right position according 00345 to the distances of the slitlets to each other 00346 (output of the north-south test). 00347 This means that the rows must be realigned by a 00348 fraction of a pixel to accomodate non-integer slit 00349 length. The fractional realignment is done by using 00350 the spline interpolation algorithm splint in connection 00351 with the algorithm spline of N.R. 00352 This algorithms assume that each row is a tabulated 00353 function. The first derivatives of the interpolating 00354 function at the first and last point must be given. 00355 These are set higher than 1xe^30, so the routine 00356 sets the corresponding boundary condition for a natural 00357 spline, with zero second derivative on that boundary. 00358 Each row is rescaled so that the total flux is 00359 conserved. 00360 ---------------------------------------------------------------------------*/ 00361 00362 /* <python> */ 00363 OneCube * fineTuneCubeBySpline ( OneCube * cube, 00364 float * correct_diff_dist ) ; 00365 /* </python> */ 00366 00367 /*---------------------------------------------------------------------------- 00368 Function : calibrate_ns_test() 00369 In : ns_image: north-south image 00370 n_slitlets: number of slitlets 00371 halfWidth: half width of the box in which the lines 00372 are fit by a gaussian 00373 fwhm: first guess of the full width at half maximum 00374 minDiff: minimum amplitude below which the fit 00375 will not be carried through 00376 estimated_dist: estimated average distance of spectra 00377 devtol: maximal pixel deviation of the distances from 00378 slitlet center 00379 Out : array of the distances of the slitlets 00380 from each other 00381 Job : determines the distances of the spectra from the center 00382 of the slitlets to be able to find the correct angle of 00383 the north-south entrance slit. 00384 ---------------------------------------------------------------------------*/ 00385 00386 /* <python> */ 00387 float * calibrate_ns_test( OneImage * ns_image, 00388 int n_slitlets, 00389 int halfWidth, 00390 float fwhm, 00391 float minDiff, 00392 float estimated_dist, 00393 float devtol, 00394 int bottom, 00395 int top ) ; 00396 /* </python> */ 00397 00398 /* <python> */ 00399 OneImage * maketrueResamp ( OneImage * calibImage, float * distances, OneImage * wavemap ); 00400 /* </python> */ 00401 00402 #endif
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001