Changeset 2719
- Timestamp:
- Dec 15, 2004, 2:46:22 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/pmSubtractSky.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/pmSubtractSky.c
r2588 r2719 6 6 * @author GLG, MHPCC 7 7 * 8 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-12- 01 21:46:06$8 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2004-12-16 00:46:22 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 17 17 #include "psConstants.h" 18 18 19 // XXX: this is pmFit in pmSubtractBias.c, and psFit here.19 // XXX: this is pmFit in pmSubtractBias.c, named psFit here. 20 20 typedef enum { 21 21 PM_FIT_NONE, ///< No fit … … 38 38 return(numBits); 39 39 } 40 41 42 40 43 41 psU64 getHighestPriorityStatOption(psU64 statOptions) … … 123 121 } 124 122 123 /****************************************************************************** 124 buildPolyTerms(): this routine computes a 2-D array polyTerms[] that holds 125 terms for the polynomial that is used to model the sky background. We use 126 this array primarily for convenience in many computations involving that sky 127 model polynomials. It is defined as: 128 polyTerms[i][0] = the power to which X is raised in the i-th term of in an 129 poly-order sky background polynomial. 130 131 polyTerms[i][1] = the power to which Y is raised in the i-th term of in an 132 poly-order sky background polynomial. 133 *****************************************************************************/ 134 psS32 **buildPolyTerms(psS32 polyOrder) 135 { 136 psS32 i=0; 137 psS32 order = 0; 138 psS32 num=0; 139 psS32 localPolyTerms= (((polyOrder+1) * (polyOrder + 2)) / 2); 140 141 // We create the data structure which we hold the xy order of each coeff. 142 psS32 **polyTerms = (psS32 **) psAlloc(localPolyTerms * sizeof(psS32 *)); 143 for (i=0; i < localPolyTerms ; i++) { 144 polyTerms[i] = (psS32 *) psAlloc(2 * sizeof(psS32)); 145 } 146 147 i=0; 148 // This code segment loops through each term i in the polynomial and 149 // calculates the power to which x/y are raised in that i-th term. 150 // We first do the 0-order terms, then the 1-order terms, etc. 151 for (order=0;order<=polyOrder;order++) { 152 for (num=0;num<=order;num++) { 153 polyTerms[i][0] = order-num; 154 polyTerms[i][1] = num; 155 i++; 156 } 157 } 158 159 return(polyTerms); 160 } 161 162 #define PS_TWENTY 20 163 164 // XXX: Use variable size arrays for polynomial sums. 165 /** @brief This procedure calculates various combinations of powers of x and y 166 * and stores them in the data structure sums[][]. After it completes: 167 * sums[i][j] == x^i * y^j 168 */ 169 void buildSums(psF64 x, 170 psF64 y, 171 psF64 sums[PS_TWENTY][PS_TWENTY], 172 psS32 polyOrder) 173 { 174 psS32 i = 0; 175 psS32 j = 0; 176 psF64 xSum = 0.0; 177 psF64 ySum = 0.0; 178 179 xSum = 1.0; 180 ySum = 1.0; 181 for(i=0;i<=polyOrder;i++) { 182 ySum = xSum; 183 for(j=0;j<=polyOrder;j++) { 184 sums[i][j] = ySum; 185 ySum*= y; 186 } 187 xSum*= x; 188 } 189 } 190 191 /****************************************************************************** 192 193 *****************************************************************************/ 194 psPolynomial2D *ImageFitPolynomial(psPolynomial2D *myPoly, 195 psImage *binnedImage, 196 psImage *maskImage) 197 { 198 PS_POLY_CHECK_NULL(myPoly, NULL); 199 PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL); 200 PS_INT_CHECK_NON_EQUALS(myPoly->nX, myPoly->nY, NULL); 201 PS_IMAGE_CHECK_NULL(binnedImage, NULL); 202 PS_IMAGE_CHECK_EMPTY(binnedImage, NULL); 203 PS_IMAGE_CHECK_TYPE(binnedImage, PS_TYPE_F32, NULL); 204 PS_IMAGE_CHECK_NULL(maskImage, NULL); 205 PS_IMAGE_CHECK_EMPTY(maskImage, NULL); 206 PS_IMAGE_CHECK_TYPE(maskImage, PS_TYPE_U8, NULL); 207 PS_IMAGE_CHECK_SIZE_EQUAL(binnedImage, maskImage, NULL); 208 psS32 i; 209 psS32 j; 210 psS32 x; 211 psS32 y; 212 psS32 aRow; 213 psS32 aCol; 214 psS32 polyOrder = myPoly->nX; 215 psS32 localPolyTerms= (((polyOrder+1) * (polyOrder + 2)) / 2); 216 psS32 **polyTerms = buildPolyTerms(polyOrder); 217 psF64 sums[PS_TWENTY][PS_TWENTY]; 218 psImage *A = psImageAlloc(localPolyTerms+1, localPolyTerms+1, PS_TYPE_F64); 219 psVector *B = psVectorAlloc(localPolyTerms+1, PS_TYPE_F64); 220 psVector *outPerm = NULL; 221 222 for(i=0;i<A->numRows;i++) { 223 for(j=0;j<A->numCols;j++) { 224 A->data.F64[i][j] = 0.0; 225 } 226 } 227 for(i=0;i<B->n;i++) { 228 B->data.F64[i] = 0.0; 229 } 230 231 for (x=0;x<binnedImage->numRows;x++) { 232 for (y=0;y<binnedImage->numCols;y++) { 233 if (maskImage->data.U8[x][y] != 0) { 234 buildSums((psF64) x, (psF64) y, sums, polyOrder); 235 236 /************************************************************ 237 Equation (7) from the ADD describes 16 linear equations. 238 The i-th equation is simply the partial derivative of the 239 sky background polynomial (1) w.r.t. to the i-th term in 240 that polynomial. The i-th equation is stored in row i of 241 matrix A[][] (matrix A[][] has origin (1,1), not (0,0)). To 242 compute A[i][j] we simply multiply the j-th term of the Sky 243 Background Polynomial (SBP) by the i-th term of SBP. 244 ************************************************************/ 245 for (aRow=0;aRow<localPolyTerms;aRow++) { 246 for (aCol=0;aCol<localPolyTerms;aCol++) { 247 A->data.F64[aRow][aCol]+= 248 (sums[ polyTerms[aCol][0] ][ polyTerms[aCol][1] ] * 249 sums[ polyTerms[aRow][0] ][ polyTerms[aRow][1] ]); 250 } 251 } 252 253 // Build the B[] vector, which is the right-hand side of (7). 254 for (i=0;i<=localPolyTerms;i++) { 255 B->data.F64[i]+= binnedImage->data.F32[x][y] * 256 sums[ polyTerms[i][0] ][ polyTerms[i][1] ]; 257 } 258 } 259 } 260 } 261 psImage *ALUD = psMatrixLUD(NULL, outPerm, A); 262 psVector *C = psMatrixLUSolve(C, ALUD, B, outPerm); 263 264 for (i=0;i<localPolyTerms;i++) { 265 myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ] = C->data.F64[i]; 266 } 267 268 for (i=0;i<localPolyTerms;i++) { 269 psFree(polyTerms[i]); 270 } 271 psFree(polyTerms); 272 psFree(A); 273 psFree(ALUD); 274 psFree(B); 275 psFree(C); 276 psFree(outPerm); 277 278 return(myPoly); 279 } 280 125 281 126 282 /****************************************************************************** 127 283 psReadout pmSubtractSky(): 128 284 129 XXX: use static vectors for myStats .285 XXX: use static vectors for myStats, and the binned image 130 286 *****************************************************************************/ 131 287 psReadout *pmSubtractSky(psReadout *in, … … 136 292 float clipSD) 137 293 { 138 if (fitSpec == NULL) { 294 // Return the original input readout if the fit specs are poorly defined. 295 if ((fitSpec == NULL) || 296 ((fit == PM_FIT_NONE) || (fit == PM_FIT_SPLINE))) { 139 297 return(in); 140 298 } 141 if ((fit != PM_FIT_POLYNOMIAL) && (fit != PM_FIT_SPLINE)) {142 // No fit is specified.143 return(in);144 }145 146 299 psImage *origImage = in->image; 147 300 psImage *maskImage = in->mask; 148 301 psImage *binnedImage = NULL; 149 302 psPolynomial2D *myPoly; 150 psSpline1D *mySpline;151 303 152 304 psStatsOptions statOptions = stats->options; … … 154 306 //XXX psWarning(PS_ERR_UNKNOWN,true, "Multiple statistical options have been requested.\n"); 155 307 statOptions = getHighestPriorityStatOption(statOptions); 308 if (statOptions <= 0) { 309 psLogMsg(__func__, PS_LOG_WARN, 310 "WARNING: pmSubtractSky(): unallowable stats->options was requested\n"); 311 return(in); 312 } 156 313 } 157 314 158 315 // Bin the input image according to input parameters. 159 if ((binFactor <= 0) || 160 (stats == NULL)) {316 if ((binFactor <= 0) || (stats == NULL)) { 317 // Simply use the original image: no binning. 161 318 if (binFactor <= 0) { 162 319 psLogMsg(__func__, PS_LOG_WARN, … … 169 326 binnedImage = origImage; 170 327 } else { 328 // Call a private function to do the binning. 171 329 binnedImage = binImage(origImage, binFactor, statOptions); 172 330 } … … 175 333 if (clipSD <= 0.0) { 176 334 psLogMsg(__func__, PS_LOG_WARN, 177 "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD) 178 ; 335 "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD); 179 336 } else { 337 // Determine the mean and standard deviation of the binned image. 180 338 psF64 binnedMean; 181 339 psF64 binnedStdev; … … 189 347 psFree(myStats); 190 348 349 // Clip all pixels which are more than clipSD sigmas from the mean. 350 // XXX: Is this correct? We simply set the mask. 351 // XXX: we must unset this later since we modify the image mask. 352 // XXX: Determine which pixels, mask or image, should be clipped. 191 353 for (int row = 0; row < binnedImage->numRows ; row++) { 192 354 for (int col = 0; col < binnedImage->numCols ; col++) { … … 201 363 // XXX: fit the polynomial to the binned image 202 364 if (fit == PM_FIT_POLYNOMIAL) { 203 // Fit a polynomial to the old overscan vector.204 365 myPoly = (psPolynomial2D *) fitSpec; 205 myPoly = psImageFitPolynomial(myPoly, origImage); 366 367 // XXX Ensure that the polynomial is of type Chebyshev. 368 myPoly = ImageFitPolynomial(myPoly, binnedImage, maskImage); 369 206 370 // XXX Do we need to do something with ordinate scaling if Chebyshev? 207 371 binnedImage = psImageEvalPolynomial(binnedImage, myPoly); 208 209 } else if (fit == PM_FIT_SPLINE) {210 // Fit a spline to the old overscan vector.211 mySpline = (psSpline1D *) fitSpec;212 // XXX: What do we do? We don't have 2-D splines.213 return(in);214 372 } 215 373 216 374 //Subtract the polynomially fitted image from the original image 217 375 if (binFactor <= 0) { 376 // The binned image is the same size as the original image. 218 377 for (int row = 0; row < origImage->numRows ; row++) { 219 378 for (int col = 0; col < origImage->numCols ; col++) { … … 231 390 232 391 } 392 393 if (!((binFactor <= 0) || (stats == NULL))) { 394 psFree(binnedImage); 395 } 396 233 397 return(in); 234 398 }
Note:
See TracChangeset
for help on using the changeset viewer.
