Changeset 14983 for trunk/psLib/src/imageops/psImageMapFit.c
- Timestamp:
- Sep 21, 2007, 5:05:50 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageMapFit.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageMapFit.c
r14960 r14983 7 7 * @author Eugene Magnier, IfA 8 8 * 9 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $10 * @date $Date: 2007-09-2 1 02:45:33$9 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-09-22 03:05:50 $ 11 11 * 12 12 * Copyright 2007 Institute for Astronomy, University of Hawaii … … 18 18 19 19 #include <stdio.h> 20 #include "psMemory.h" 20 21 #include "psError.h" 21 22 #include "psAbort.h" … … 57 58 // no spatial information, just calculate mean & stdev 58 59 if ((Nx == 1) && (Ny == 1)) { 59 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);60 61 // XXX does ROBUST_MEDIAN work with weight?62 psVectorStats (stats, f, NULL, mask, maskValue);63 64 map->map->data.F32[0][0] = stats->robustMedian;65 map->error->data.F32[0][0] = stats->robustStdev;66 psFree (stats);67 return true;60 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 61 62 // XXX does ROBUST_MEDIAN work with weight? 63 psVectorStats (stats, f, NULL, mask, maskValue); 64 65 map->map->data.F32[0][0] = stats->robustMedian; 66 map->error->data.F32[0][0] = stats->robustStdev; 67 psFree (stats); 68 return true; 68 69 } 69 70 70 71 if (Nx == 1) { 71 psAbort ("un-implemented edge case");72 goto insert;72 psAbort ("un-implemented edge case"); 73 goto insert; 73 74 } 74 75 if (Ny == 1) { 75 psAbort ("un-implemented edge case");76 goto insert;76 psAbort ("un-implemented edge case"); 77 goto insert; 77 78 } 78 79 … … 82 83 83 84 for (int i = 0; i < 3; i++) { 84 SAv[i] = SAm[i] + 1;85 // TAv[i] = TAm[i] + 1;85 SAv[i] = SAm[i] + 1; 86 // TAv[i] = TAm[i] + 1; 86 87 } 87 88 sA = SAv + 1; 88 89 // tA = TAv + 1; 89 90 90 // elements of the matrix equation Ax = B; we are solving for the vector x 91 // elements of the matrix equation Ax = B; we are solving for the vector x 91 92 psImage *A = psImageAlloc (Nx*Ny, Nx*Ny, PS_TYPE_F32); 92 93 psVector *B = psVectorAlloc (Nx*Ny, PS_TYPE_F32); … … 95 96 psVectorInit (B, 0.0); 96 97 97 // we are looping over the Nx,Ny image map elements; 98 // the matrix equation contains Nx*Ny rows and columns 98 // we are looping over the Nx,Ny image map elements; 99 // the matrix equation contains Nx*Ny rows and columns 99 100 // for (int n = 1; n < Nx - 1; n++) { 100 101 // for (int m = 1; m < Ny - 1; m++) { 101 102 102 103 // float Total = 0.0; 103 104 for (int n = 0; n < Nx; n++) { 104 for (int m = 0; m < Ny; m++) {105 // define & init summing variables106 float rx_rx_ry_ry = 0;107 float rx_rx_dy_ry = 0;108 float dx_rx_ry_ry = 0;109 float dx_rx_dy_ry = 0;110 float fi_rx_ry = 0;111 float rx_rx_py_py = 0;112 float rx_rx_qy_py = 0;113 float dx_rx_py_py = 0;114 float dx_rx_qy_py = 0;115 float fi_rx_py = 0;116 float px_px_ry_ry = 0;117 float px_px_dy_ry = 0;118 float qx_px_ry_ry = 0;119 float qx_px_dy_ry = 0;120 float fi_px_ry = 0;121 float px_px_py_py = 0;122 float px_px_qy_py = 0;123 float qx_px_py_py = 0;124 float qx_px_qy_py = 0;125 float fi_px_py = 0;126 127 // generate the sums for the fitting matrix element I,J128 // I = n + nX*m129 // J = (n + jn) + nX*(m + jm)130 for (int i = 0; i < x->n; i++) {131 132 if (mask && (mask->data.U8[i] & maskValue)) continue;133 134 // base coordinate offset for this point (x,y) relative to this map element (n,m)135 // float dx = x->data.F32[i] - psImageBinningGetFineX (map->binning, n + 0.5);136 // float dy = y->data.F32[i] - psImageBinningGetFineY (map->binning, m + 0.5);137 138 float dx = psImageBinningGetRuffX (map->binning, x->data.F32[i]) - (n + 0.5);139 float dy = psImageBinningGetRuffY (map->binning, y->data.F32[i]) - (m + 0.5);140 141 // edge cases to include:142 bool edgeX = false;143 edgeX |= ((n == 1) && (dx < -1.0));144 edgeX |= ((n == Nx - 2) && (dx > +1.0));145 146 bool edgeY = false;147 edgeY |= ((m == 1) && (dy < -1.0));148 edgeY |= ((m == Ny - 2) && (dy > +1.0));149 150 // skip points outside of 2x2 grid centered on n,m:151 if (!edgeX && (fabs(dx) > 1.0)) continue;152 if (!edgeY && (fabs(dy) > 1.0)) continue;153 154 // related offset values155 float rx = 1.0 - dx;156 float ry = 1.0 - dy;157 float px = 1.0 + dx;158 float py = 1.0 + dy;159 float qx = -dx;160 float qy = -dy;161 162 // data value & weight for this point163 float fi = f->data.F32[i];164 float wt = 1.0;165 if (df != NULL) {166 if (df->data.F32[i] == 0.0) {167 wt = 0.0;168 } else {169 wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0170 }171 }172 173 // sum the appropriate elements for the different quadrants174 175 int Qx = (dx >= 0) ? 1 : 0;176 if (n == 0) Qx = 1;177 if (n == Nx - 1) Qx = 0;178 179 int Qy = (dy >= 0) ? 1 : 0;180 if (m == 0) Qy = 1;181 if (m == Ny - 1) Qy = 0;182 183 // points at offset 1,1184 if ((Qx == 1) && (Qy == 1)) {185 rx_rx_ry_ry += rx*rx*ry*ry*wt;186 rx_rx_dy_ry += rx*rx*dy*ry*wt;187 dx_rx_ry_ry += dx*rx*ry*ry*wt;188 dx_rx_dy_ry += dx*rx*dy*ry*wt;189 fi_rx_ry += fi*rx*ry*wt;190 }191 // points at offset 1,0192 if ((Qx == 1) && (Qy == 0)) {193 rx_rx_py_py += rx*rx*py*py*wt;194 rx_rx_qy_py += rx*rx*qy*py*wt;195 dx_rx_py_py += dx*rx*py*py*wt;196 dx_rx_qy_py += dx*rx*qy*py*wt;197 fi_rx_py += fi*rx*py*wt;198 }199 // points at offset 0,1200 if ((Qx == 0) && (Qy == 1)) {201 px_px_ry_ry += px*px*ry*ry*wt;202 px_px_dy_ry += px*px*dy*ry*wt;203 qx_px_ry_ry += qx*px*ry*ry*wt;204 qx_px_dy_ry += qx*px*dy*ry*wt;205 fi_px_ry += fi*px*ry*wt;206 }207 // points at offset 0,0208 if ((Qx == 0) && (Qy == 0)) {209 px_px_py_py += px*px*py*py*wt;210 px_px_qy_py += px*px*qy*py*wt;211 qx_px_py_py += qx*px*py*py*wt;212 qx_px_qy_py += qx*px*qy*py*wt;213 fi_px_py += fi*px*py*wt;214 }215 } 216 217 // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm),218 // jn,jm = -1 to +1. Convert the sums above into the correct coefficients219 sA[-1][-1] = qx_px_qy_py;220 sA[-1][ 0] = qx_px_ry_ry + qx_px_py_py;221 sA[-1][+1] = qx_px_dy_ry;222 sA[ 0][-1] = rx_rx_qy_py + px_px_qy_py;223 sA[ 0][ 0] = rx_rx_ry_ry + px_px_ry_ry + rx_rx_py_py + px_px_py_py;224 sA[ 0][+1] = rx_rx_dy_ry + px_px_dy_ry;225 sA[+1][-1] = dx_rx_qy_py;226 sA[+1][ 0] = dx_rx_ry_ry + dx_rx_py_py;227 sA[+1][+1] = dx_rx_dy_ry;228 229 insert:230 // I[ 0][ 0] = index for this n,m element:231 I = n + Nx * m;232 B->data.F32[I] = fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py;233 234 // insert these values into their corresponding locations in A, B235 // float Sum = 0.0;236 for (int jn = -1; jn <= +1; jn++) {237 if (n + jn < 0) continue;238 if (n + jn >= Nx) continue;239 for (int jm = -1; jm <= +1; jm++) {240 if (m + jm < 0) continue;241 if (m + jm >= Ny) continue;242 J = (n + jn) + Nx * (m + jm);243 A->data.F32[J][I] = sA[jn][jm];244 // fprintf (stderr, "A %d %d (%d %d : %d %d): %f\n", I, J, n, m, n + jn, m + jm, sA[jn][jm]);245 // Sum += sA[jn][jm];246 }247 }248 // fprintf (stderr, "B %d (%d %d) : %f : %f\n", I, n, m, B->data.F32[I], Sum);249 // Total += Sum;250 }105 for (int m = 0; m < Ny; m++) { 106 // define & init summing variables 107 float rx_rx_ry_ry = 0; 108 float rx_rx_dy_ry = 0; 109 float dx_rx_ry_ry = 0; 110 float dx_rx_dy_ry = 0; 111 float fi_rx_ry = 0; 112 float rx_rx_py_py = 0; 113 float rx_rx_qy_py = 0; 114 float dx_rx_py_py = 0; 115 float dx_rx_qy_py = 0; 116 float fi_rx_py = 0; 117 float px_px_ry_ry = 0; 118 float px_px_dy_ry = 0; 119 float qx_px_ry_ry = 0; 120 float qx_px_dy_ry = 0; 121 float fi_px_ry = 0; 122 float px_px_py_py = 0; 123 float px_px_qy_py = 0; 124 float qx_px_py_py = 0; 125 float qx_px_qy_py = 0; 126 float fi_px_py = 0; 127 128 // generate the sums for the fitting matrix element I,J 129 // I = n + nX*m 130 // J = (n + jn) + nX*(m + jm) 131 for (int i = 0; i < x->n; i++) { 132 133 if (mask && (mask->data.U8[i] & maskValue)) continue; 134 135 // base coordinate offset for this point (x,y) relative to this map element (n,m) 136 // float dx = x->data.F32[i] - psImageBinningGetFineX (map->binning, n + 0.5); 137 // float dy = y->data.F32[i] - psImageBinningGetFineY (map->binning, m + 0.5); 138 139 float dx = psImageBinningGetRuffX (map->binning, x->data.F32[i]) - (n + 0.5); 140 float dy = psImageBinningGetRuffY (map->binning, y->data.F32[i]) - (m + 0.5); 141 142 // edge cases to include: 143 bool edgeX = false; 144 edgeX |= ((n == 1) && (dx < -1.0)); 145 edgeX |= ((n == Nx - 2) && (dx > +1.0)); 146 147 bool edgeY = false; 148 edgeY |= ((m == 1) && (dy < -1.0)); 149 edgeY |= ((m == Ny - 2) && (dy > +1.0)); 150 151 // skip points outside of 2x2 grid centered on n,m: 152 if (!edgeX && (fabs(dx) > 1.0)) continue; 153 if (!edgeY && (fabs(dy) > 1.0)) continue; 154 155 // related offset values 156 float rx = 1.0 - dx; 157 float ry = 1.0 - dy; 158 float px = 1.0 + dx; 159 float py = 1.0 + dy; 160 float qx = -dx; 161 float qy = -dy; 162 163 // data value & weight for this point 164 float fi = f->data.F32[i]; 165 float wt = 1.0; 166 if (df != NULL) { 167 if (df->data.F32[i] == 0.0) { 168 wt = 0.0; 169 } else { 170 wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0 171 } 172 } 173 174 // sum the appropriate elements for the different quadrants 175 176 int Qx = (dx >= 0) ? 1 : 0; 177 if (n == 0) Qx = 1; 178 if (n == Nx - 1) Qx = 0; 179 180 int Qy = (dy >= 0) ? 1 : 0; 181 if (m == 0) Qy = 1; 182 if (m == Ny - 1) Qy = 0; 183 184 // points at offset 1,1 185 if ((Qx == 1) && (Qy == 1)) { 186 rx_rx_ry_ry += rx*rx*ry*ry*wt; 187 rx_rx_dy_ry += rx*rx*dy*ry*wt; 188 dx_rx_ry_ry += dx*rx*ry*ry*wt; 189 dx_rx_dy_ry += dx*rx*dy*ry*wt; 190 fi_rx_ry += fi*rx*ry*wt; 191 } 192 // points at offset 1,0 193 if ((Qx == 1) && (Qy == 0)) { 194 rx_rx_py_py += rx*rx*py*py*wt; 195 rx_rx_qy_py += rx*rx*qy*py*wt; 196 dx_rx_py_py += dx*rx*py*py*wt; 197 dx_rx_qy_py += dx*rx*qy*py*wt; 198 fi_rx_py += fi*rx*py*wt; 199 } 200 // points at offset 0,1 201 if ((Qx == 0) && (Qy == 1)) { 202 px_px_ry_ry += px*px*ry*ry*wt; 203 px_px_dy_ry += px*px*dy*ry*wt; 204 qx_px_ry_ry += qx*px*ry*ry*wt; 205 qx_px_dy_ry += qx*px*dy*ry*wt; 206 fi_px_ry += fi*px*ry*wt; 207 } 208 // points at offset 0,0 209 if ((Qx == 0) && (Qy == 0)) { 210 px_px_py_py += px*px*py*py*wt; 211 px_px_qy_py += px*px*qy*py*wt; 212 qx_px_py_py += qx*px*py*py*wt; 213 qx_px_qy_py += qx*px*qy*py*wt; 214 fi_px_py += fi*px*py*wt; 215 } 216 } 217 218 // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm), 219 // jn,jm = -1 to +1. Convert the sums above into the correct coefficients 220 sA[-1][-1] = qx_px_qy_py; 221 sA[-1][ 0] = qx_px_ry_ry + qx_px_py_py; 222 sA[-1][+1] = qx_px_dy_ry; 223 sA[ 0][-1] = rx_rx_qy_py + px_px_qy_py; 224 sA[ 0][ 0] = rx_rx_ry_ry + px_px_ry_ry + rx_rx_py_py + px_px_py_py; 225 sA[ 0][+1] = rx_rx_dy_ry + px_px_dy_ry; 226 sA[+1][-1] = dx_rx_qy_py; 227 sA[+1][ 0] = dx_rx_ry_ry + dx_rx_py_py; 228 sA[+1][+1] = dx_rx_dy_ry; 229 230 insert: 231 // I[ 0][ 0] = index for this n,m element: 232 I = n + Nx * m; 233 B->data.F32[I] = fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py; 234 235 // insert these values into their corresponding locations in A, B 236 // float Sum = 0.0; 237 for (int jn = -1; jn <= +1; jn++) { 238 if (n + jn < 0) continue; 239 if (n + jn >= Nx) continue; 240 for (int jm = -1; jm <= +1; jm++) { 241 if (m + jm < 0) continue; 242 if (m + jm >= Ny) continue; 243 J = (n + jn) + Nx * (m + jm); 244 A->data.F32[J][I] = sA[jn][jm]; 245 // fprintf (stderr, "A %d %d (%d %d : %d %d): %f\n", I, J, n, m, n + jn, m + jm, sA[jn][jm]); 246 // Sum += sA[jn][jm]; 247 } 248 } 249 // fprintf (stderr, "B %d (%d %d) : %f : %f\n", I, n, m, B->data.F32[I], Sum); 250 // Total += Sum; 251 } 251 252 } 252 253 // fprintf (stderr, "Total: %f\n", Total); … … 256 257 psVectorInit (Empty, 0); 257 258 for (int i = 0; i < Nx*Ny; i++) { 258 if (A->data.F32[i][i] == 0.0) {259 Empty->data.S8[i] = 1;260 for (int j = 0; j < Nx*Ny; j++) {261 A->data.F32[i][j] = 0.0;262 A->data.F32[j][i] = 0.0;263 }264 A->data.F32[i][i] = 1.0;265 B->data.F32[i] = 0.0;266 }259 if (A->data.F32[i][i] == 0.0) { 260 Empty->data.S8[i] = 1; 261 for (int j = 0; j < Nx*Ny; j++) { 262 A->data.F32[i][j] = 0.0; 263 A->data.F32[j][i] = 0.0; 264 } 265 A->data.F32[i][i] = 1.0; 266 B->data.F32[i] = 0.0; 267 } 267 268 } 268 269 … … 274 275 psImage *vector = psImageAlloc (1, B->n, PS_TYPE_F32); 275 276 for (int n = 0; n < B->n; n++) { 276 vector->data.F32[0][n] = B->data.F32[n];277 vector->data.F32[0][n] = B->data.F32[n]; 277 278 } 278 279 … … 284 285 285 286 if (!psMatrixGJSolveF32(A, B)) { 286 psAbort ("failed on linear equations");287 psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations. Returning NULL.\n");288 psFree (A);289 psFree (B);290 return false;291 } 292 287 psAbort ("failed on linear equations"); 288 psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations. Returning NULL.\n"); 289 psFree (A); 290 psFree (B); 291 return false; 292 } 293 293 294 // set bad values to NaN 294 295 for (int i = 0; i < Nx*Ny; i++) { 295 if (Empty->data.S8[i]) {296 B->data.F32[i] = NAN;297 }296 if (Empty->data.S8[i]) { 297 B->data.F32[i] = NAN; 298 } 298 299 } 299 300 300 301 301 302 for (int n = 0; n < Nx; n++) { 302 for (int m = 0; m < Ny; m++) {303 I = n + Nx * m;304 map->map->data.F32[m][n] = B->data.F32[I];305 map->error->data.F32[m][n] = sqrt(A->data.F32[I][I]);306 }303 for (int m = 0; m < Ny; m++) { 304 I = n + Nx * m; 305 map->map->data.F32[m][n] = B->data.F32[I]; 306 map->error->data.F32[m][n] = sqrt(A->data.F32[I][I]); 307 } 307 308 } 308 309 … … 353 354 psVector *mask = inMask; 354 355 if (!inMask) { 355 mask = psVectorAlloc (x->n, PS_TYPE_U8);356 psVectorInit (mask, 0);356 mask = psVectorAlloc (x->n, PS_TYPE_U8); 357 psVectorInit (mask, 0); 357 358 } 358 359 … … 368 369 if (!psImageMapFit(map, mask, maskValue, x, y, f, df)) { 369 370 psError(PS_ERR_UNKNOWN, false, "Could not fit image map.\n"); 370 psFree(resid);371 if (!inMask) psFree (mask);371 psFree(resid); 372 if (!inMask) psFree (mask); 372 373 return false; 373 374 } … … 377 378 psError(PS_ERR_UNKNOWN, false, "Failure in psImageMapEvalVector().\n"); 378 379 psFree(resid); 379 if (!inMask) psFree (mask);380 if (!inMask) psFree (mask); 380 381 return false; 381 382 } 382 383 for (int i = 0 ; i < f->n ; i++) { 383 resid->data.F32[i] = (f->data.F32[i] - fit->data.F32[i]);384 resid->data.F32[i] = (f->data.F32[i] - fit->data.F32[i]); 384 385 } 385 386 … … 388 389 psFree(resid); 389 390 psFree(fit); 390 if (!inMask) psFree (mask);391 if (!inMask) psFree (mask); 391 392 return false; 392 393 } … … 404 405 // recovery is not allowed with this scheme 405 406 for (psS32 i = 0; i < resid->n; i++) { 406 // XXX this prevents recovery of previously masked values407 // XXX this prevents recovery of previously masked values 407 408 if (mask->data.U8[i] & maskValue) { 408 409 continue; … … 410 411 411 412 if ((resid->data.F32[i] - meanValue > maxClipValue) || (resid->data.F32[i] - meanValue < minClipValue)) { 412 psTrace("psLib.imageops", 6, "Masking element %d : %f vs %f : resid is %f\n", i, f->data.F32[i], fit->data.F32[i], resid->data.F32[i]);413 mask->data.U8[i] |= 0x01;413 psTrace("psLib.imageops", 6, "Masking element %d : %f vs %f : resid is %f\n", i, f->data.F32[i], fit->data.F32[i], resid->data.F32[i]); 414 mask->data.U8[i] |= 0x01; 414 415 continue; 415 416 }
Note:
See TracChangeset
for help on using the changeset viewer.
