00001 #include <stdio.h>
00002 #include <math.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <time.h>
00006 #include <sys/time.h>
00007 #include <ctype.h>
00008
00009
00010 extern int verbose;
00011 static float lastr1, lastr2, lastyc, lastxc;
00012 float sdisk_xc=2047.5, sdisk_yc=2047.5, sdisk_r, chicircle;
00013 static unsigned char *mask, *mask2, *masks;
00014 static int lastnx, lastny;
00015 static float gsmooth_width = 2.3;
00016 static long *jstarts, *jvalues, *jstarts_s, *jvalues_s, *jstarts2, *jvalues2;
00017 static int num_inann, num_inann2, num_inanns, num_in2use;
00018 static int *in2use, *thann;
00019 static int *ixnann, *iynann;
00020 static long *inann, *inanns, *inann2;
00021 static float *annth, *annthr;
00022 int scounts ;
00023 typedef unsigned char byte;
00024 #define MAX(a,b) (((a)>(b))?(a):(b))
00025 #define MIN(a,b) (((a)<(b))?(a):(b))
00026 #define ABS(x) ((x)>=0?(x):-(x))
00027 #define ALN2I 1.442695022
00028 #define TINY 1.0e-5
00029 #define MAXNITER 100
00030
00031 float xcenters[MAXNITER], ycenters[MAXNITER], radiai[MAXNITER];
00032 long pcounts[MAXNITER], nextcenter;
00033 int max4histogram = 10000;
00034 void mmq(float *x, int n, float *max, float *min);
00035 void indexf(int n, float ra[],int indx[]);
00036 long getindexofmax(int *x, int n);
00037 int pit(float *qxbase, float *qybase, int nxq, int npow, double *a, double *cfbase, double *fbase );
00038 float parabolicmax5(int *x, int nx);
00039 void sobel_index(float *x, int nx, int ny, long *iq, int nindex, float **grad, float **ang);
00040 void mm_f(float *x, int n, float *max, float *min);
00041 void mm_int(int *x, int n, int *max, int *min);
00042 void indexf(int n, float ra[],int indx[]);
00043 int circle_fit_lsq(float *x, float *y, float *w, int n, float *xc_out, float *yc_out, float *r_out, float *chi_out);
00044 int key_locations(int *array, int n, int *nv, int **counts, int **values, int ***indexptrs);
00045 long hist_max_xvalue(float *x, int n);
00046 int *hist_array(float *x, int n, int *nh, int *hmin);
00047 int hist_max_freq(float *x, int n);
00048 void getmin9(int *p, int ix, int iy, int nx, float *x0, float *y0);
00049 void zeroinonlimb(float *xlimb, float *ylimb, int nin, float dr, float *g);
00050 void minihough(int nc, float *xlimb, float *ylimb, int niter);
00051 void decomp(double *x, int n, int nd);
00052 void solve(double *a, double *b, int n, int nd);
00053 int pit(float *qxbase, float *qybase, int nxq, int npow, double *a, double *cfbase, double *fbase );
00054 float parabolicmax5(int *x, int nx);
00055 void printarray(float *x, int n);
00056 void printintarray(int *x, int n);
00057 #define EPSILON 1.e-10
00058 double systime();
00059
00060 double systime()
00061 {
00062 double t;
00063 struct timeval tp;
00064 struct timezone tzp;
00065 gettimeofday(&tp, &tzp);
00066 t = (double) tp.tv_sec + .000001* (double) tp.tv_usec;
00067 return t;
00068 }
00069
00070 float rsun_offset(int wavelength)
00071 {
00072 switch (wavelength) {
00073 case 94: return 7.3;
00074 case 131: return 7.6;
00075 case 171: return 9.3;
00076 case 193: return 9.9;
00077 case 211: return 10.4;
00078 case 304: return 18.5;
00079 case 335: return 11.0;
00080 case 1600: return 1.4;
00081 case 1700: return 0.2;
00082 case 4500: return -1.2;
00083 default: return FP_NAN;
00084 }
00085 }
00086
00087 void getmin9(int *p, int ix, int iy, int nx, float *x0, float *y0)
00088 {
00089
00090
00091 float f11, f12, f13, f21, f22, f23, f31, f32, f33;
00092 float toler, fx, fy, t, fxx, fyy, fxy;
00093 int *pp;
00094 long off;
00095
00096
00097 off = (iy-1)*nx;
00098 pp = p + ix + off -1;
00099 f11 = (float) *pp++; f21 = (float) *pp++; f31 = (float) *pp;
00100 pp = pp + nx - 2;
00101 f12 = (float) *pp++; f22 = (float) *pp++; f32 = (float) *pp;
00102 pp = pp + nx - 2;
00103 f13 = (float) *pp++; f23 = (float) *pp++; f33 = (float) *pp;
00104
00105 fx = 0.5 * ( f32 - f12 ); fy = 0.5 * ( f23 - f21 );
00106 t = 2.* ( f22 );
00107 fxx = f32 + f12 - t; fyy = f23 + f21 - t;
00108
00109 if (f33 < f11) { if (f33 < f31) {
00110 if (f33 < f13) fxy = f33+f22-f32-f23; else fxy = f23+f12-f22-f13; }
00111 else {
00112 if (f31 < f13) fxy = f32+f21-f31-f22; else fxy = f23+f12-f22-f13; }
00113 } else { if (f11 < f31) {
00114 if (f11 < f13) fxy = f22+f11-f21-f12; else fxy = f23+f12-f22-f13; }
00115 else {
00116 if (f31 < f13) fxy = f32+f21-f31-f22; else fxy = f23+f12-f22-f13; }
00117 }
00118 t = -1./(fxx *fyy - fxy *fxy);
00119 *x0 = t * (fx * fyy - fy * fxy);
00120 *y0 = t * (fy * fxx - fx * fxy);
00121 if ( ABS(*x0) >= 0.75 || ABS(*x0) >= 0.75 ) { *x0 = -fx/fxx; *y0 = -fy/fyy; }
00122 return;
00123 }
00124
00125 void zeroinonlimb(float *xlimb, float *ylimb, int nin, float dr, float *g)
00126 {
00127
00128
00129
00130 int i, j, n;
00131 long *index;
00132 float *x, *y, *w;
00133 float rdlimb;
00134
00135 n = 0;
00136 index = malloc(nin * sizeof(long));
00137 i = 0;
00138 for (j=0;j<nin;j++) {
00139 rdlimb = hypotf(xlimb[j]-sdisk_xc, ylimb[j]-sdisk_yc) - sdisk_r;
00140 if ( fabsf(rdlimb) < dr) { index[i] = j; i++; }
00141 }
00142 n = i;
00143 x = malloc(n * sizeof(float)); y = malloc(n * sizeof(float));
00144 w = malloc(n * sizeof(float));
00145 for (i=0;i<n;i++) {
00146 j = index[i];
00147 x[i] = xlimb[j]; y[i] = ylimb[j]; w[i] = g[j];
00148 }
00149 circle_fit_lsq(x, y, w, n, &sdisk_xc, &sdisk_yc, &sdisk_r, &chicircle);
00150 if (verbose>2) printf("zeroinonlimb: sdisk_xc, sdisk_yc, sdisk_r = %g, %g, %g\n",sdisk_xc, sdisk_yc, sdisk_r);
00151 free(index);
00152 free(x); free(y); free(w);
00153 }
00154
00155 #define NXC 11
00156 #define NYC 11
00157 #define NRC 11
00158 void minihough(int nc, float *xlimb, float *ylimb, int niter)
00159 {
00160
00161
00162
00163
00164
00165 float xq, yq, xoffset, yoffset, *rdlimb, dx, dy, dr, xc1, yc1, rx, dxprev, dyprev;
00166 int mhcount[NXC * NYC], k, ixc, iyc, irc, ic, inx, ix, iy, *hr, nh, hmin, rmax, iq, ndone;
00167 double t0, t1, t2, t3, t4, t1s, tstart, tend, dt1, dt2;
00168 tstart = systime();
00169 rdlimb = (float *) malloc(nc * sizeof(float));
00170 dxprev = dyprev = 5.0;
00171 if (verbose>2) printf("minihough, nc = %d\n", nc);
00172 if (niter > MAXNITER) {
00173 if (verbose>1) printf("iteration count request (%d) exceeds MAXNITER (%d)\n", niter, MAXNITER);
00174 niter = MAXNITER; }
00175
00176 dt1 = dt2 = 0.0;
00177 for (k=0;k<niter;k++) {
00178 t0 = systime();
00179
00180 xoffset = sdisk_xc - (float) (NXC/2);
00181 yoffset = sdisk_yc - (float) (NYC/2);
00182 ic = 0;
00183 rmax = inx = 0;
00184 for (iyc=0;iyc<NYC;iyc++) {
00185
00186 dy = (float) iyc + yoffset;
00187 for (ixc=0;ixc<NXC;ixc++) {
00188 dx = (float) ixc + xoffset;
00189
00190 for (irc=0;irc<nc;irc++) {
00191 xq = xlimb[irc] - dx;
00192 yq = ylimb[irc] - dy;
00193 rdlimb[irc] = hypotf(xq, yq) - sdisk_r;
00194 }
00195
00196 iq = hist_max_freq(rdlimb, nc);
00197 mhcount[ic] = -iq;
00198 if (iq > rmax) { rmax = iq; inx = ic; }
00199 ic++;
00200
00201 }
00202 }
00203 t1 = systime();
00204 dt1 += t1 - t0;
00205
00206
00207
00208 ix = inx%NXC; iy = inx/NXC;
00209 dx = ix - (float) (NXC/2);
00210 dy = iy - (float) (NYC/2);
00211
00212
00213 if (ix <= 0 || ix >= (NXC-1)) {
00214 fprintf(stderr, "x center max at edge, ix = %d\n", ix); return; }
00215 if (iy <= 0 || iy >= (NYC-1)) {
00216 fprintf(stderr, "y center max at edge, iy = %d\n", iy); return; }
00217
00218
00219 getmin9(mhcount, ix, iy, NXC, &xc1, &yc1);
00220
00221
00222 dx = (dx + xc1) * 0.5;
00223 dy = (dy + yc1) * 0.5;
00224
00225
00226
00227 dxprev = fabsf(dx);
00228 dyprev = fabsf(dy);
00229 if (verbose>4) printf("dx, dy = %g, %g\n", dx, dy);
00230
00231 for (irc=0;irc<nc;irc++) {
00232 xq = xlimb[irc] - dx - sdisk_xc;
00233 yq = ylimb[irc] - dy - sdisk_yc;
00234 rdlimb[irc] = hypotf(xq, yq) - sdisk_r;
00235 }
00236
00237 hr = hist_array(rdlimb, nc, &nh, &hmin);
00238 rx = parabolicmax5(hr, nh) + (float) hmin;
00239 free(hr);
00240 dr = rx * 0.5;
00241 if (verbose>4) printf("Hough dx, dy, dr = %g, %g, %g\n", dx, dy, dr);
00242 sdisk_xc += dx;
00243 sdisk_yc += dy;
00244 sdisk_r += dr;
00245 xcenters[nextcenter] = sdisk_xc; ycenters[nextcenter] = sdisk_yc;
00246 radiai[nextcenter] = sdisk_r; pcounts[nextcenter] = rmax; nextcenter++;
00247
00248 if ((dx*dx + dy*dy) < 0.0002 && fabsf(dr) < 0.01) {
00249 if (verbose>2) printf("close enough, k = %d\n", k); break;
00250 }
00251 t2 = systime();
00252 dt2 += t2 - t1;
00253 }
00254 ndone = nextcenter;
00255
00256 if (verbose>3) {
00257 printf("$xcenters =");
00258 printarray(xcenters, ndone);
00259
00260 printf("$ycenters =");
00261 printarray(ycenters, ndone);
00262
00263 printf("$radiai =");
00264 printarray(radiai, ndone);
00265
00266 printf("$pcounts =");
00267 for (k=0;k<ndone;k++) {
00268 if (k%6 == 0) printf("\n");
00269 printf("%12.5e", (float) pcounts[k]);
00270 }
00271 printf("\n");
00272 printf("minihough times %8.3f %8.3f\n", dt1, dt2);
00273 tend = systime();
00274 printf("total minihough time %8.3f\n", tend - tstart);
00275 }
00276 free(rdlimb);
00277 }
00278
00279 void printarray(float *x, int n)
00280 {
00281
00282 int k;
00283 printf("%d count array\n", n);
00284 for (k=0;k<n;k++) {
00285 if (k%6 == 0) printf("\n");
00286 printf("%13.5e", x[k]);
00287 }
00288 printf("\n");
00289 }
00290
00291 void printintarray(int *x, int n)
00292 {
00293
00294 int k;
00295 printf("%d count array\n", n);
00296 for (k=0;k<n;k++) {
00297 if (k%8 == 0) printf("\n");
00298 printf("%10d", x[k]);
00299 }
00300 printf("\n");
00301 }
00302
00303 int circle_fit_lsq(float *x, float *y, float *w, int n, float *xc_out, float *yc_out, float *r_out, float *chi_out)
00304 {
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 double xxyy,
00319 sx,sy,sw,swinv,
00320 sxx8,syy8,sxy8,sxxy8,syxy8,sxxyy8,
00321 xt,xtp,top,bot,
00322 x8,y8,w8,x08,y08,rsq,chisq8,
00323 f,g,h,p,q,t,
00324 a0,b0,c0,d0,det,
00325 gamma, gamma0,g0inv;
00326
00327 float *xp, *yp, *wp;
00328 int i, nptw, iflag = 0;
00329 int j, k, nn;
00330
00331
00332
00333
00334
00335
00336
00337
00338 sx = 0.0; sy = 0.0; sw = 0.0; nptw = 0;
00339
00340 nn = n;
00341 xp = x; yp = y; wp = w;
00342 sx = sy = sw = 0.0;
00343 while (nn--) { w8 = *wp++; sw += w8; sx += w8 * *xp++; sy += w8 * *yp++; }
00344
00345 swinv = 1./sw;
00346 sx = sx*swinv; sy = sy*swinv;
00347
00348
00349
00350 sxx8 = syy8 = sxy8 = sxxy8 = syxy8 = sxxyy8 = 0.0;
00351 nn = n;
00352 xp = x; yp = y; wp = w;
00353 while (nn--) {
00354 w8 = *wp++; x8 = *xp++ - sx; y8 = *yp++ - sy;
00355 xxyy = x8*x8 + y8*y8; sxx8 += x8*x8*w8;
00356 syy8 += y8*y8*w8; sxy8 += x8*y8*w8;
00357 sxxy8 += x8*xxyy*w8; syxy8 += y8*xxyy*w8;
00358 sxxyy8 += xxyy*xxyy*w8;
00359 }
00360
00361 f = swinv*(3.*sxx8 + syy8);
00362 g = swinv*(sxx8 + 3.*syy8);
00363 h = 2.*swinv*sxy8;
00364 p = swinv*sxxy8;
00365 q = swinv*syxy8;
00366 t = swinv*sxxyy8;
00367
00368
00369
00370 gamma0 = swinv*(sxx8 + syy8);
00371 g0inv = 1./gamma0;
00372
00373 a0 = -4.;
00374 b0 = (f*g - t - h*h)*g0inv*g0inv;
00375 c0 = (t*(f + g) - 2.*(p*p + q*q))*g0inv*g0inv*g0inv;
00376 d0 = (t*(h*h - f*g) + 2.*(p*p*g + q*q*f) - 4.*p*q*h)*g0inv*g0inv*g0inv*g0inv;
00377
00378
00379
00380 xt = 1.;
00381 for(i= 0; i < 10; i++)
00382 {top = xt*(xt*(xt*(xt + a0) + b0) + c0) + d0;
00383 bot = xt*(xt*(4.*xt + 3.*a0) + 2.*b0) + c0;
00384 xtp = xt -top/bot;
00385 if(fabs(xtp-xt) < EPSILON) break;
00386 xt = xtp;
00387 }
00388 if (i >= 10) { iflag = 2; xtp = 1.0; }
00389
00390 gamma = gamma0*xtp;
00391 det = h*h - (f-gamma)*(g-gamma);
00392
00393
00394
00395 if(fabs(det) <= 1.0e-16) {return 3;}
00396
00397 x08 = (q*h - p*(g-gamma))/det;
00398 y08 = (p*h - q*(f-gamma))/det;
00399
00400 rsq = x08*x08 + y08*y08 + gamma;
00401 if (rsq < 0.0) { return 4; }
00402 *r_out = (float) sqrt (rsq);
00403
00404
00405
00406 *xc_out = (float) (x08 + sx);
00407 *yc_out = (float) (y08 + sy);
00408
00409
00410
00411 if(n == 3) {
00412 *chi_out = 0.0;
00413 }
00414 else {
00415 chisq8 = 0.0;
00416 nn = n; wp = w; xp = x; yp = y;
00417 while (nn--) {
00418 w8 = *wp++; x8 = *xp++ - sx; y8 = *yp++ - sy;
00419 chisq8 +=
00420 w8*((x08+sx-x8)*(x08+sx-x8) + (y08+sy-y8)*(y08+sy-y8) - rsq)*
00421 ((x08+sx-x8)*(x08+sx-x8) + (y08+sy-y8)*(y08+sy-y8) -rsq);
00422 }
00423 *chi_out = (float) (chisq8/(4.0*rsq)/(n-3));
00424 }
00425 return iflag;
00426 }
00427
00428 void indexf(int n, float ra[],int indx[])
00429
00430 {
00431 int l,j,ir,i,indxt;
00432 float q;
00433
00434 for (i=0;i<n;i++) indx[i] = i;
00435 l = (n/2);
00436 ir = n-1;
00437 for (;;) {
00438 if (l > 0)
00439 q=ra[(indxt=indx[--l])];
00440 else {
00441 q=ra[(indxt=indx[ir])];
00442 indx[ir]=indx[0];
00443 if (--ir == 0) {indx[0]=indxt;return; }
00444 }
00445 i = l;
00446 j = l + l + 1;
00447 while (j <= ir) {
00448 if (j < ir && ra[indx[j]] < ra[indx[j+1]]) j++;
00449 if (q < ra[indx[j]]) {
00450 indx[i] = indx[j];
00451 j += (i=j) + 1;
00452 }
00453 else j = ir + 1;
00454 }
00455 indx[i] =indxt;
00456 }
00457 }
00458
00459 int key_locations(int *array, int n, int *nv, int **counts, int **values, int ***indexptrs)
00460
00461
00462
00463
00464 {
00465 int iq, i, nd, j, range, type, m, k, mq;
00466 int min, max;
00467 int nuniq;
00468 int *vscratch, *p, *q, val_sym, cnt_sym, indexsymarr;
00469 int *countp, **qp, **qpbase, **qpstart, *valueoffsets, *pv;
00470
00471 mm_int(array, n, &max, &min);
00472 range = max - min + 1;
00473
00474 vscratch = (int *) malloc(range * sizeof (int));
00475 valueoffsets = (int *) malloc(range * sizeof (int));
00476 bzero( (void *) vscratch, range * sizeof (int));
00477 bzero( (void *) valueoffsets, range * sizeof (int));
00478 nuniq = 0;
00479
00480 q = array;
00481 for (j=0;j<n;j++) {
00482 i = *q++ - min;
00483 p = vscratch + i;
00484 if ( *p == 0 ) { nuniq++; }
00485 *p += 1;
00486 }
00487
00488
00489
00490 *nv = nuniq;
00491
00492
00493 p = *values = (int *) malloc(nuniq * sizeof (int));
00494 q = *counts = (int *) malloc(nuniq * sizeof (int));
00495
00496 *indexptrs = qpbase = (int **) malloc(nuniq * sizeof (int *));
00497 qp = qpstart = (int **) malloc(nuniq * sizeof (int *));
00498 i = 0;
00499 pv = valueoffsets;
00500 for (j=0;j<range;j++) {
00501 int cq = *(vscratch + j);
00502 if ( cq ) {
00503 *p++ = j + min;
00504 *q++ = cq;
00505
00506 *qpbase++ = *qp++ = (int *) malloc(cq * sizeof (int));
00507 *pv++ = i; i++;
00508 if (i > nuniq) { printf("internal error 1 in key_locations\n"); return -1; }
00509 } else *pv++ = -1;
00510 }
00511
00512
00513
00514 q = array;
00515 for (j=0;j<n;j++) {
00516 i = *q++ - min;
00517
00518 k = *(valueoffsets + i);
00519 if (k < 0) printf("bad k = %d\n", k);
00520 if (k >= nuniq) printf("bad k = %d\n", k);
00521 *(qpstart[k])++ = j;
00522 }
00523
00524 free(vscratch);
00525 free(qpstart);
00526 free(valueoffsets);
00527 return 1;
00528 }
00529
00530 void mm_f(float *x, int n, float *max, float *min)
00531 {
00532 float rmin, rmax;
00533
00534 if (n <= 0 ) { printf("bad count in mm_f, n = %d\n",n); return; }
00535 rmax = rmin = *x++; n--;
00536 while (n--) { if (*x > rmax) rmax = *x; if (*x < rmin) rmin = *x; x++; }
00537 *min = rmin; *max = rmax;
00538 return;
00539 }
00540
00541 void mm_int(int *x, int n, int *max, int *min)
00542 {
00543 int rmin, rmax;
00544
00545 if (n <= 0 ) { printf("bad count in mm_int, n = %d\n",n); return; }
00546 rmax = rmin = *x++; n--;
00547 while (n--) { if (*x > rmax) rmax = *x; if (*x < rmin) rmin = *x; x++; }
00548 *min = rmin; *max = rmax;
00549 return;
00550 }
00551
00552 long getindexofmax(int *x, int n)
00553
00554 {
00555 int rmax;
00556 long inx, i;
00557 if (n <= 0 ) { printf("bad count in getindexofmax, n = %d\n",n); return -1; }
00558 rmax = *x++; n--; inx = i = 0;
00559 while (n--) { i++; if (*x > rmax) { rmax = *x; inx = i; } x++; }
00560 return inx;
00561 }
00562
00563
00564
00565 long hist_max_xvalue(float *x, int n)
00566
00567
00568 {
00569 int *hist, xq;
00570 float xmax, xmin;
00571 long max, min, imax, i, iq, range;
00572 mm_f(x, n, &xmax, &xmin);
00573 max = lrintf(xmax);
00574 min = lrintf(xmin);
00575 range = max - min + 1;
00576 if (range > max4histogram) { printf("values in array > %d\n", max4histogram); return 0; }
00577
00578 hist = (int *) malloc(sizeof(int) * range);
00579 bzero((void *) hist, sizeof(int) * range);
00580 for (i=0;i<n;i++) {
00581 iq = lrintf(x[i]) - min;
00582 hist[iq] += 1;
00583 }
00584
00585 imax = 0;
00586 xq = 0;
00587 for (i=0;i<range;i++) {
00588 if (hist[i] > xq) { imax = i; xq = hist[i]; }
00589 }
00590
00591 free(hist);
00592 imax = imax + min;
00593 return imax;
00594 }
00595
00596 int hist_max_freq(float *x, int n)
00597
00598
00599 {
00600 int *hist, xq;
00601 float xmax, xmin;
00602 long max, min, imax, i, iq, range;
00603 mm_f(x, n, &xmax, &xmin);
00604 max = lrintf(xmax);
00605 min = lrintf(xmin);
00606 range = max - min + 1;
00607 if (range > max4histogram) { printf("values in array > %d\n", max4histogram); return 0; }
00608
00609 hist = (int *) malloc(sizeof(int) * range);
00610 bzero((void *) hist, sizeof(int) * range);
00611 for (i=0;i<n;i++) {
00612 iq = lrintf(x[i]) - min;
00613 hist[iq] += 1;
00614 }
00615
00616 imax = 0;
00617 xq = 0;
00618 for (i=0;i<range;i++) {
00619 if (hist[i] > xq) { imax = i; xq = hist[i]; }
00620 }
00621
00622 free(hist);
00623 return xq;
00624 }
00625
00626 int *hist_array(float *x, int n, int *nh, int *hmin)
00627
00628
00629 {
00630 int *hist, xq;
00631 float xmax, xmin;
00632 long max, min, i, iq, range;
00633 mm_f(x, n, &xmax, &xmin);
00634 max = lrintf(xmax);
00635 min = lrintf(xmin);
00636 *nh = range = max - min + 1;
00637 *hmin = (int) min;
00638 if (range > max4histogram) { printf("values in array > %d\n", max4histogram); return 0; }
00639
00640 hist = (int *) malloc(sizeof(int) * range);
00641 bzero((void *) hist, sizeof(int) * range);
00642 for (i=0;i<n;i++) {
00643 iq = lrintf(x[i]) - min;
00644 hist[iq] += 1;
00645 }
00646 return hist;
00647 }
00648
00649 void decomp(double *x, int n, int nd)
00650
00651
00652
00653 {
00654 register double sum1, sum2, *p1, *p2, *p3, *p4;
00655 double *qd, * q2, *q1, div, *p;
00656 int nq, mq, lq, k;
00657 p1 = x;
00658 div = 1.0 / *p1; nq = n-1; while (nq--) { p1 += nd; *p1 *= div; }
00659 nq = n-1; k = 1; qd = x + 1 + nd;
00660 while (nq--) {
00661
00662 sum1 = *qd; mq = k; p1 = p2 = qd;
00663 while (mq--) { p1 -= nd; p2--; sum1 -= (*p1) * (*p2); }
00664 *qd = sum1;
00665 q1 = q2 = qd; lq = n - k - 1;
00666 while (lq--) { q1 += nd; q2 += 1; mq = k;
00667 sum1 = *q1; sum2 = *q2;
00668 p1 = p4 = qd; p2 = q1; p3 = q2;
00669 while (mq--) { p1 -= nd; p2 -= 1; p3 -= nd; p4 -= 1;
00670 sum1 -= (*p1) * (*p2); sum2 -= (*p3) * (*p4); }
00671 *q2 = sum2; *q1 = sum1 / *qd;
00672 }
00673 k++; qd += (nd + 1); }
00674 }
00675
00676 void solve(double *a, double *b, int n, int nd)
00677 {
00678 register double sum, *p1, *p2;
00679 double *qd, *q1, div;
00680 int nq, mq, lq, k;
00681
00682 p1 = a; q1 = b; *q1 = *q1 / *p1; q1++;
00683 nq = n-1; k = 1; qd = a + 1 + nd;
00684 while (nq--) { sum = 0.0; mq = k;
00685 p1 = qd; p2 = q1;
00686 while (mq--) { p1 -= nd; p2--; sum += (*p1) * (*p2); }
00687 *q1 = (*q1 - sum) / *qd;
00688 k++; qd += (nd + 1); q1++; }
00689 nq = n-1; k = n - 1; qd = a + nd*nd -2; q1 = b + n - 2;
00690 while (nq--) { sum = 0.0; mq = n - k;
00691 p1 = qd; p2 = q1;
00692 while (mq--) { p2++; sum += (*p1) * (*p2); p1 += nd; }
00693 *q1 = *q1 - sum;
00694 k--; qd -= (nd + 1); q1--; }
00695 }
00696
00697 int pit(float *qxbase, float *qybase, int nxq, int npow, double *a, double *cfbase, double *fbase )
00698
00699 {
00700 double sum, *f, *cf;
00701 float *qx, *qy;
00702 int i, n, ib, ie, k;
00703 cf = cfbase; f = fbase;
00704 qx = qxbase; qy = qybase;
00705
00706
00707
00708 n = nxq; while (n--) *f++ = *qx++;
00709 *a = nxq;
00710 for (k=0;k < (2*npow);k++) { sum = 0.0; f = fbase; n = nxq; qx = qxbase;
00711 while (n--) {sum += *f; *f = (*f) * (*qx++); f++; }
00712 ib = (k+1-npow) > 0 ? (k+1-npow) : 0;
00713 ie = (k+1) > (npow) ? (npow) : (k+1);
00714 for (i=ib;i<=ie;i++) {
00715 *( a + i + (npow+1)*(ie+ib-i) ) = sum;
00716 }
00717 }
00718
00719 f = fbase; n = nxq; while (n--) *f++ = *qy++;
00720 for (k=0;k <= (npow);k++) { sum = 0.0; f = fbase; n = nxq; qx = qxbase;
00721 while (n--) {sum += *f; *f = (*f) * (*qx++); f++; }
00722 *cf++ = sum; }
00723
00724
00725 decomp(a, npow+1, npow+1);
00726 solve(a, cfbase, npow+1, npow+1);
00727
00728
00729 return 1;
00730 }
00731
00732 float parabolicmax5(int *x, int nx)
00733
00734
00735 {
00736 long i, i1, i2;
00737 float xq, xpit[5], ypit[5];
00738 float *qybase;
00739 double *cfbase, *fbase, *a;
00740 int npow = 2, *ixp;
00741
00742 i = getindexofmax(x, nx);
00743 if (nx < 5) {
00744 printf("parabolicmax5 input too small for fit, using max index only, no interpolation\n");
00745 xq = (float) i;
00746 return xq;
00747 } else {
00748 if ((i+2) >= nx) i = nx - 3;
00749 if (i < 2) i = 2;
00750 i1 = i - 2;
00751 ixp = x + i1;
00752 for (i=0;i<5;i++) xpit[i] = (float) i;
00753 for (i=0;i<5;i++) ypit[i] = (float) *ixp++;
00754 cfbase = (double *) malloc((npow+1) * sizeof(double));
00755 fbase = (double *) malloc( nx * sizeof(double));
00756 a = (double *) malloc((npow+1)*(npow+1) * sizeof(double));
00757 pit( xpit, ypit, 5, 2, a, cfbase, fbase);
00758
00759 if (cfbase[2] == 0.0) {
00760 printf("parabolicmax5 - singularity, using max index only, no interpolation\n");
00761 xq = (float) i;
00762 return xq;
00763 }
00764 xq = - cfbase[1]*.5/cfbase[2];
00765 xq = xq + i1;
00766 free(a); free(fbase); free(cfbase);
00767 return xq;
00768 }
00769 }
00770
00771 void sobel_index(float *x, int nx, int ny, long *iq, int nindex, float **grad, float **ang)
00772
00773
00774
00775
00776 {
00777 float gx, gy, xq;
00778 float *pbot, *ptop, *pt2, *pt3;
00779 int jj;
00780 long in;
00781 pt2 = *grad = malloc(sizeof(float) * nindex);
00782 pt3 = *ang = malloc(sizeof(float) * nindex);
00783
00784 for (jj=0; jj<nindex; jj++) {
00785 in = iq[jj];
00786
00787
00788 pbot = x + in - nx -1;
00789 ptop = x + in + nx +1;
00790
00791 gx = gy = *ptop-- - *pbot++;
00792 gy = gy + 2 * (*ptop-- - *pbot++);
00793 xq = *pbot - *ptop;
00794 gy = gy - xq;
00795 gx = gx + xq + 2 * (*(pbot + nx) - *(ptop - nx));
00796
00797 *pt2++ = 0.125 * hypotf(gx, gy);
00798 *pt3++ = atan2f(gy, gx);
00799 }
00800 return;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 void gsmooth_index(float *x, float fwhm, int nx, int ny, long *iq, int nindex, float *result);
00836 void gsmooth_index(float *x, float fwhm, int nx, int ny, long *iq, int nindex, float *result)
00837
00838
00839
00840
00841 {
00842 int jj, in, i, i1, i2, n2, ng, n, ns;
00843 float *pt1, *pt2, *pt3, *gkern, width, sum, gsum, sumg, wq, xq;
00844 width = 0.6005612 * fwhm;
00845 pt2 = result;
00846
00847 if ( width < 0.25 ) {
00848 float *pt = x;
00849 for (jj=0; jj<nindex; jj++) { *pt2++ = *pt++; }
00850 return;
00851 }
00852
00853 n2 = MIN( (int) (gsmooth_width * width), nx/2 - 2);
00854 n2 = MAX( n2, 1);
00855 ng = 2 * n2 +1;
00856 gkern = (float *) malloc( (ng) * sizeof(float));
00857 n = ng; wq = (float) (-n2); pt3 = gkern; gsum = 0.0;
00858 while (n--)
00859 { sum = wq/width; wq++; xq = exp(-sum*sum); *pt3++ = xq; gsum += xq; }
00860 for (jj=0; jj<nindex; jj++) {
00861 in = iq[jj];
00862 i = in % nx;
00863 i2 = i + n2;
00864 i1 = i - n2;
00865 sum = 0;
00866
00867 if (i1 < 0) {
00868
00869 pt3 = gkern - i1;
00870 ns = ng + i1;
00871 pt1 = x + in - n2 - i1;
00872 sumg = sum = 0.0;
00873 while (ns--) { sumg += *pt3; sum += *pt1++ * *pt3++; }
00874 *pt2++ = sum / sumg;
00875 } else if (i2 >= nx) {
00876
00877 pt3 = gkern;
00878 pt1 = x + in - n2;
00879 ns = ng -i2 + nx - 1;
00880 sumg = sum = 0.0;
00881 while (ns--) { sumg += *pt3; sum += *pt1++ * *pt3++; }
00882 *pt2++ = sum / sumg;
00883 } else {
00884
00885 ns = ng; pt1 = x + in - n2; pt3 = gkern;
00886 while (ns--) { sum += *pt1++ * *pt3++; }
00887 *pt2++ = sum / gsum;
00888 }
00889 }
00890 free(gkern);
00891 return;
00892 }
00893
00894 void gsmoothy_index(float *x, float fwhm, int nx, int ny, long *iq, int nindex, float *result);
00895 void gsmoothy_index(float *x, float fwhm, int nx, int ny, long *iq, int nindex, float *result)
00896
00897
00898
00899
00900 {
00901 int jj, in, j, j1, j2, n2, ng, n, ns;
00902 float *pt1, *pt2, *pt3, *gkern, width, sum, gsum, sumg, wq, xq;
00903 width = 0.6005612 * fwhm;
00904 pt2 = result;
00905
00906 if ( width < 0.25 ) {
00907 float *pt = x;
00908 for (jj=0; jj<nindex; jj++) { *pt2++ = *pt++; }
00909 }
00910
00911 n2 = MIN( (int) (gsmooth_width * width), ny/2 - 2);
00912 n2 = MAX( n2, 1);
00913 ng = 2 * n2 +1;
00914 gkern = (float *) malloc( (ng) * sizeof(float));
00915 n = ng; wq = (float) (-n2); pt3 = gkern; gsum = 0.0;
00916 while (n--)
00917 { sum = wq/width; wq++; xq = exp(-sum*sum); *pt3++ = xq; gsum += xq; }
00918 for (jj=0; jj<nindex; jj++) {
00919 in = iq[jj];
00920 j = in / nx;
00921 j2 = j + n2;
00922 j1 = j - n2;
00923 sum = 0;
00924
00925 if (j1 < 0) {
00926
00927 pt3 = gkern - j1;
00928 ns = ng + j1;
00929 pt1 = x + in - j * nx;
00930 sumg = sum = 0.0;
00931 while (ns--) { sumg += *pt3; sum += *pt1 * *pt3++; pt1 += nx; }
00932 *pt2++ = sum / sumg;
00933 } else if (j2 >= ny) {
00934
00935 pt3 = gkern;
00936 pt1 = x + in - n2 * nx;
00937 ns = ng -j2 + ny - 1;
00938 sumg = sum = 0.0;
00939 while (ns--) { sumg += *pt3; sum += *pt1 * *pt3++; pt1 += nx; }
00940 *pt2++ = sum / sumg;
00941 } else {
00942
00943 ns = ng; pt1 = x + in - n2 * nx; pt3 = gkern;
00944 while (ns--) { sum += *pt1 * *pt3++; pt1 += nx; }
00945 *pt2++ = sum / gsum;
00946 }
00947 }
00948 free(gkern);
00949 return;
00950 }
00951
00952 void fill_image(float *x, int nx, int ny, long *iq, int nindex, float *fill);
00953 void fill_image(float *x, int nx, int ny, long *iq, int nindex, float *fill)
00954
00955
00956 {
00957 int jj;
00958 float *ptf = fill;
00959 long *pt;
00960 pt = iq;
00961 for (jj=0; jj<nindex; jj++) {
00962 x[*pt++] = *ptf++;
00963 }
00964 return;
00965 }
00966
00967 void fill_indices(float *x, int nx, int ny, long *iq, int nindex);
00968 void fill_indices(float *x, int nx, int ny, long *iq, int nindex)
00969
00970
00971 {
00972 int jj;
00973 long *pt = iq;
00974 for (jj=0; jj<nindex; jj++) {
00975 x[*pt++] = 1.0;
00976 }
00977 return;
00978 }
00979
00980 int limbcompute(float *x, int nx, int ny, float xcguess, float ycguess, float rguess, float rrange,
00981 int limbmode, int useprevflag, float fwhm)
00982 {
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 float r1, r2, r1s, r2s, da;
00993
00994 float *grad, *ang, *fscratch;
00995 float *result;
00996 int *in2;
00997 int margin, nxny, nxd2, nyd2, nv, num_in2, n2use;
00998 int *values, *counts, **in4annulus;
00999 float rmax, limbtolerance;
01000 float *xlimb, *ylimb, *xlimbptr, *ylimbptr;
01001 int i, j, k, njs, njs2, njs_s, jprev, jprev2, jprev_s, nq;
01002 int makeannflag;
01003 int debug = 1;
01004 double t0, t1, t2, t3, t4, t1s, tstart, tend;
01005 tstart = systime();
01006 nxny = nx*ny;
01007 nxd2 = nx/2; nyd2 = ny/2;
01008
01009 if (nx != lastnx || ny != lastny) {
01010 free(inann); free(inanns); free(inann2);
01011 inann = malloc(sizeof(long) * nxny);
01012 inanns = malloc(sizeof(long) * nxny);
01013 inann2 = malloc(sizeof(long) * nxny);
01014 lastnx = nx; lastny = ny;
01015 }
01016
01017 makeannflag = 1;
01018 r1 = rguess - rrange;
01019 r2 = rguess + rrange;
01020 if (r1 == lastr1 && r2 == lastr2 ) {
01021
01022 if ( (fabsf(lastxc-xcguess) <= 10) && fabsf(lastyc-ycguess) <= 10) makeannflag = 0;
01023 }
01024 if (makeannflag) {
01025 if (verbose > 1) {
01026 printf("r1, lastr1, r2, lastr2 = %g %g %g %g\n", r1, lastr1, r2, lastr2);
01027 printf("lastxc, xcguess, lastyc, ycguess = %g %g %g %g\n", lastxc, xcguess, lastyc, ycguess);
01028 }
01029 }
01030 if (makeannflag) {
01031 float r1uv, r2uv;
01032
01033 r1s = r1 - 7; r2s = r2 + 7;
01034
01035 r1uv = r1 - 1; r2uv = r2 + 1;
01036 lastr1 = r1;
01037 lastr2 = r2;
01038 lastxc = xcguess;
01039 lastyc = ycguess;
01040
01041 r1 = r1 * r1; r2 = r2 * r2;
01042 r1s = r1s * r1s; r2s = r2s * r2s;
01043 r1uv = r1uv * r1uv; r2uv = r2uv * r2uv;
01044
01045 num_inann = num_inann2 = num_inanns = 0;
01046 margin = 25;
01047 rmax = 2100.;
01048
01049 jprev = jprev_s = jprev2 = -1;
01050 for (j=margin; j<(ny-margin); j++) {
01051 float rys = powf ( j - ycguess, 2);
01052 for (i=margin; i<(nx-margin); i++) {
01053 float rxs = powf( i - xcguess, 2);
01054 float rs = rys + rxs;
01055
01056 if (rs > r1s && rs < r2s) {
01057
01058 float rccd = hypotf((float) (i-nxd2), (float) (j-nyd2));
01059 if (rccd < rmax) {
01060 int iq = i + nx * j;
01061
01062
01063 inanns[num_inanns++] = iq;
01064 if (rs > r1uv && rs < r2uv) {
01065
01066
01067 inann2[num_inann2++] = iq;
01068 if (rs > r1 && rs < r2) {
01069
01070
01071 inann[num_inann++] = iq;
01072 }
01073 }
01074 }
01075 }
01076 }
01077 }
01078
01079
01080 free(ixnann);
01081 free(iynann);
01082 free(annth);
01083 free(annthr);
01084 free(thann);
01085 free(in2use);
01086 ixnann = malloc(sizeof(int) * num_inann);
01087 iynann = malloc(sizeof(int) * num_inann);
01088 annth = malloc(sizeof(float) * num_inann);
01089 annthr = malloc(sizeof(float) * num_inann);
01090 thann = malloc(sizeof(int) * num_inann);
01091 in2use = malloc(sizeof(int) * num_inann);
01092 for (k=0;k<num_inann;k++) {
01093 float xq;
01094 long in = inann[k];
01095 i = in % nx;
01096 j = in / nx;
01097 ixnann[k] = i;
01098 iynann[k] = j;
01099 xq = 5.729578e+01 * atan2f((float) j - ycguess,(float) i - xcguess);
01100
01101 thann[k] = (int) lroundf(xq);
01102
01103 if (thann[k] < 0) thann[k] = thann[k] + 360;
01104 annth[k] = xq;
01105
01106 annthr[k] = annth[k] + 180.;
01107 if (annthr[k] > 360.) annthr[k] = annthr[k] - 360.;
01108
01109
01110 }
01111
01112
01113
01114
01115
01116 key_locations(thann, num_inann, &nv, &counts, &values, &in4annulus);
01117
01118
01119
01120
01121
01122 {
01123 int max, min, nq, *p1, *p2, nc;
01124 mm_int(counts, nv, &max, &min);
01125 nq = (int) (0.75 * (float) max);
01126 p1 = in2use;
01127 nc = 0;
01128 for (j=0;j<nv;j++) {
01129
01130 if (counts[j] >= nq) {
01131
01132 p2 = in4annulus[j];
01133 for (i=0;i<counts[j];i++) {
01134 *p1++ = *p2++;
01135 nc++;
01136 }
01137 free(in4annulus[j]);
01138 }
01139 }
01140
01141
01142 if (nc > num_inann) { printf("internal error, nc, num_inann = %d, %d\n", nc, num_inann); return 1; }
01143
01144
01145
01146
01147
01148 num_in2use = nc;
01149 }
01150 free(counts);
01151 free(values);
01152
01153 } else if (verbose > 1) { printf("re-using last annulus\n"); }
01154 t1 = systime();
01155 if (verbose > 0) printf("time for setup %8.3f\n", t1-tstart);
01156
01157
01158
01159 fscratch = (float *) malloc(sizeof(float) * nxny);
01160 bzero((void *) fscratch, nxny);
01161
01162 result = malloc(sizeof(float) * num_inanns);
01163 if (limbmode == 1) {
01164
01165 gsmooth_index(x, fwhm, nx, ny, inanns, num_inanns, result);
01166
01167 fill_image(fscratch, nx, ny, inanns, num_inanns, result);
01168 gsmoothy_index(fscratch, fwhm, nx, ny, inanns, num_inanns, result);
01169 fill_image(fscratch, nx, ny, inanns, num_inanns, result);
01170
01171 sobel_index(fscratch, nx, ny, inann2, num_inann2, &grad, &ang);
01172
01173
01174 fill_image(fscratch, nx, ny, inann2, num_inann2, grad);
01175 free(grad); free(ang);
01176 sobel_index(fscratch, nx, ny, inann, num_inann, &grad, &ang);
01177
01178 } else {
01179
01180 gsmooth_index(x, fwhm, nx, ny, inanns, num_inanns, result);
01181
01182 fill_image(fscratch, nx, ny, inanns, num_inanns, result);
01183
01184 gsmoothy_index(fscratch, fwhm, nx, ny, inanns, num_inanns, result);
01185 fill_image(fscratch, nx, ny, inanns, num_inanns, result);
01186
01187
01188 sobel_index(fscratch, nx, ny, inann, num_inann, &grad, &ang);
01189
01190
01191
01192 }
01193 free(fscratch);
01194 free(result);
01195 t2 = systime();
01196 if (verbose > 0) printf("time for image processing %8.3f\n", t2-t1);
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 if (limbmode == 3) da = 5.0; else da = 5.0;
01207
01208
01209 {
01210 float *fp1, *fp2, xq, gq;
01211 int *p1, *p2, iq, jq, nc, nmatch = 0;
01212 if (limbmode == 2 || limbmode == 3 || limbmode == 4) {
01213 fp1 = annthr;
01214 } else {
01215 fp1 = annth;
01216 }
01217 in2 = p1 = malloc(sizeof(int) * num_in2use);
01218 nc = 0;
01219 if (verbose > 2) printf("num_in2use %d\n", num_in2use);
01220 for (k=0;k<num_in2use;k++) {
01221 iq = in2use[k];
01222 xq = fabsf( fp1[iq] - (float) 57.29578 * ang[iq]);
01223 if ((xq <= da || xq >= (360-da)) && (grad[iq] > 0.0)) { *p1++ = iq; nc++;
01224
01225
01226
01227
01228 }
01229 }
01230 num_in2 = nc;
01231 if (verbose > 2)
01232 printf("n within 5 degrees, num_inann = %d, %d\n", num_in2, num_inann);
01233 }
01234
01235 {
01236 int *theta3, *p1, *p2, *indx, *infaint, *svalues;
01237 int keepfaint = 300, nfaint, nzones, iq, jq, nc;
01238 float *xint, *fp1, xtot, *sxint;
01239
01240 theta3 = p1 = malloc(sizeof(int) * num_in2);
01241 for (k=0;k<num_in2;k++) {
01242 *p1++ = thann[in2[k]];
01243
01244 }
01245
01246
01247 key_locations(theta3, num_in2, &nzones, &counts, &values, &in4annulus);
01248
01249 if (verbose > 2) printf("nzones = %d\n", nzones);
01250 indx = malloc(sizeof(int) * nzones);
01251
01252
01253 if (limbmode == 0 || limbmode == 3) {
01254 xint = fp1 = malloc(sizeof(float) * nzones);
01255 for (j=0;j<nzones;j++) {
01256 xtot = 0.0;
01257 nc = counts[j];
01258 p2 = in4annulus[j];
01259 for (i=0;i<nc;i++) {
01260 iq = *p2++;
01261 jq = in2[iq];
01262 xtot += (float) x[inann[jq]];
01263 }
01264 *fp1++ = xtot/(float) nc;
01265
01266 }
01267
01268
01269 indexf(nzones, xint, indx);
01270
01271 nfaint = (int) ((float) keepfaint * (float) nzones/360.);
01272 free(xint);
01273 } else {
01274
01275 nfaint = nzones;
01276 for (j=0;j<nzones;j++) { indx[j] = j; }
01277 }
01278
01279
01280
01281
01282
01283
01284 if (useprevflag) {
01285
01286 xcenters[0] = sdisk_xc; ycenters[0] = sdisk_yc; radiai[0] = sdisk_r; pcounts[0] = 0;
01287 nextcenter = 1;
01288 } else {
01289
01290
01291
01292
01293
01294 float *ixlimb, *iylimb, *rsec, *weights, rq, thq, *rdlimb;
01295 long irmax, *inx4ann;
01296 int jfaint, *indxrdlimb;
01297 ixlimb = malloc(sizeof(float) * nfaint);
01298 iylimb = malloc(sizeof(float) * nfaint);
01299 jfaint = 0;
01300 for (j=0;j<nfaint;j++) {
01301 k = indx[j];
01302
01303 nc = counts[k];
01304 p2 = in4annulus[k];
01305 if (nc >0) {
01306 if (limbmode == 1 || limbmode == 3) {
01307 rsec = malloc(sizeof(float) * nc);
01308 for (i=0;i<nc;i++) {
01309 float ix, iy;
01310 iq = *p2++;
01311 jq = in2[iq];
01312 ix = ixnann[jq];
01313 iy = iynann[jq];
01314 rsec[i] = 0.5 * hypotf( ix - xcguess, iy - ycguess);
01315 if (limbmode == 3) rsec[i] = rsec[i] * .25;
01316 }
01317
01318 irmax = hist_max_xvalue(rsec, nc);
01319
01320 rq = 2.0 * (float) irmax;
01321 if (limbmode == 3) rq = rq *4.0;
01322
01323
01324 thq = values[k] * 0.01745329;
01325 ixlimb[jfaint] = rq *cosf(thq) + xcguess;
01326 iylimb[jfaint] = rq *sinf(thq) + ycguess;
01327 free(rsec);
01328 } else {
01329
01330 float gmax;
01331 int jqgmax;
01332 gmax = -1.0E20; jqgmax = 0;
01333 for (i=0;i<nc;i++) {
01334 iq = *p2++;
01335 jq = in2[iq];
01336 if ( grad[jq] > gmax) { gmax = grad[jq]; jqgmax = jq; }
01337 }
01338 ixlimb[jfaint] = ixnann[jqgmax];
01339 iylimb[jfaint] = iynann[jqgmax];
01340
01341 }
01342 jfaint++;
01343 }
01344 }
01345
01346 if (nfaint != jfaint) printf("nfaint, jfaint do not match: %d %d\n", nfaint, jfaint);
01347 nfaint = jfaint;
01348
01349 weights = malloc(sizeof(float) * nfaint);
01350 for (j=0;j<nfaint;j++) { weights[j] = 1.0; }
01351 circle_fit_lsq(ixlimb, iylimb, weights, nfaint, &sdisk_xc, &sdisk_yc, &sdisk_r, &chicircle);
01352 if (verbose > 0)
01353 printf("sdisk_xc, sdisk_yc, sdisk_r = %g, %g, %g\n",sdisk_xc, sdisk_yc, sdisk_r);
01354
01355 xcenters[0] = sdisk_xc; ycenters[0] = sdisk_yc; radiai[0] = sdisk_r; pcounts[0] = nfaint;
01356 nextcenter = 1;
01357
01358
01359
01360
01361 rdlimb = malloc(sizeof(float) * nfaint);
01362 for (j=0;j<nfaint;j++) {
01363 rdlimb[j] = hypotf(ixlimb[j]-sdisk_xc, iylimb[j]-sdisk_yc) - sdisk_r;
01364 }
01365 indxrdlimb = malloc(sizeof(int) * nfaint);
01366 indexf(nfaint, rdlimb, indxrdlimb);
01367
01368 {
01369 float *ixlimb2, *iylimb2;
01370 int n2reject, nreject, n2use;
01371 n2reject = nfaint/4;
01372 ixlimb2 = malloc(sizeof(float) * nfaint);
01373 iylimb2 = malloc(sizeof(float) * nfaint);
01374 n2use = 0;
01375 nreject = 0;
01376 for (j=0;j<nfaint;j++) {
01377 i = indxrdlimb[j];
01378 if ( (rdlimb[i] > -7.0 ) || (nreject > n2reject) ) {
01379
01380 ixlimb2[n2use] = ixlimb[i]; iylimb2[n2use] = iylimb[i]; n2use++;
01381 } else {
01382
01383 nreject++;
01384 }
01385
01386 }
01387
01388 if (verbose > 1) printf("# of values sent to circle_fit %d\n", n2use);
01389 circle_fit_lsq(ixlimb2, iylimb2, weights, n2use, &sdisk_xc, &sdisk_yc, &sdisk_r, &chicircle);
01390 xcenters[nextcenter] = sdisk_xc; ycenters[nextcenter] = sdisk_yc;
01391 radiai[nextcenter] = sdisk_r; pcounts[nextcenter] = n2use; nextcenter++;
01392 if (verbose > 0)
01393 printf("sdisk_xc, sdisk_yc, sdisk_r = %g, %g, %g\n",sdisk_xc, sdisk_yc, sdisk_r);
01394 free(ixlimb2);
01395 free(iylimb2);
01396 }
01397 free(weights);
01398 free(ixlimb);
01399 free(iylimb);
01400 free(indxrdlimb);
01401 free(rdlimb);
01402
01403 }
01404
01405
01406 if (limbmode != 0 && limbmode != 3) {
01407 float *g3, *g3ptr;
01408
01409 if (verbose) printf("in UV or 304 zone, nfaint = %d\n", nfaint);
01410 nc = 0;
01411 for (j=0;j<nfaint;j++) {
01412 k = indx[j];
01413 nc += counts[k];
01414 }
01415 n2use = nc;
01416 xlimb = xlimbptr = malloc(sizeof(float) * n2use);
01417 ylimb = ylimbptr = malloc(sizeof(float) * n2use);
01418
01419 g3 = g3ptr = malloc(sizeof(float) * n2use);
01420
01421 for (j=0;j<nfaint;j++) {
01422 k = indx[j];
01423 nc = counts[k];
01424 p2 = in4annulus[k];
01425 if (nc >0) {
01426 for (i=0;i<nc;i++) {
01427
01428 iq = p2[i];
01429
01430 jq = in2[iq];
01431
01432 *xlimbptr++ = ixnann[jq];
01433 *ylimbptr++ = iynann[jq];
01434 *g3ptr++ = grad[jq];
01435 }
01436 }
01437 }
01438
01439 {
01440 float drs[] = {50., 35., 25.,15, 10., 5};
01441 int ndr = sizeof(drs)/sizeof(float);
01442
01443 for (k=0;k<ndr;k++) {
01444 zeroinonlimb(xlimb, ylimb, n2use, drs[k], g3);
01445 xcenters[nextcenter] = sdisk_xc; ycenters[nextcenter] = sdisk_yc;
01446 radiai[nextcenter] = sdisk_r; pcounts[nextcenter] = nc; nextcenter++;
01447 }
01448 }
01449
01450
01451 if (limbmode == 2 || limbmode == 4) {
01452 float drs[] = {3., 2., 1., 1., 1., 1., 1.};
01453 int ndr = sizeof(drs)/sizeof(float);
01454
01455 for (k=0;k<ndr;k++) {
01456 zeroinonlimb(xlimb, ylimb, n2use, drs[k], g3);
01457 xcenters[nextcenter] = sdisk_xc; ycenters[nextcenter] = sdisk_yc;
01458 radiai[nextcenter] = sdisk_r; pcounts[nextcenter] = nc; nextcenter++;
01459 }
01460 }
01461
01462 free(xlimb); free(ylimb); free(g3);
01463 }
01464
01465
01466 if (limbmode != 2 && limbmode != 4) {
01467
01468
01469 if (limbmode == 3) limbtolerance = 15; else limbtolerance = 10;
01470
01471
01472 n2use = 0;
01473 for (j=0;j<nfaint;j++) {
01474 int ncnew;
01475 k = indx[j];
01476 nc = counts[k];
01477 ncnew = 0;
01478 p2 = in4annulus[k];
01479 if (nc >0) {
01480 for (i=0;i<nc;i++) {
01481 float ix, iy, rq, drq;
01482 iq = p2[i];
01483 jq = in2[iq];
01484 ix = ixnann[jq];
01485 iy = iynann[jq];
01486
01487 rq = hypotf( ix - sdisk_xc, iy - sdisk_yc);
01488 drq = fabsf(rq - sdisk_r);
01489 if (drq < limbtolerance) {
01490
01491 p2[ncnew] = iq; ncnew++;
01492 }
01493 }
01494 }
01495 counts[k] = ncnew;
01496 n2use += ncnew;
01497 }
01498 if (verbose > 2) printf("new total after limbtolerance %d\n", n2use);
01499
01500
01501
01502 n2use = 0;
01503 for (j=0;j<nfaint;j++) {
01504 float gmean;
01505 int ncnew;
01506 k = indx[j];
01507 nc = counts[k];
01508 p2 = in4annulus[k];
01509 gmean = 0.0;
01510 ncnew = 0;
01511 if (nc >0) {
01512 for (i=0;i<nc;i++) {
01513 iq = p2[i];
01514 jq = in2[iq];
01515
01516 gmean = gmean + grad[jq];
01517 }
01518 gmean = gmean/nc;
01519
01520 gmean = gmean * 0.9;
01521 for (i=0;i<nc;i++) {
01522 iq = p2[i];
01523 jq = in2[iq];
01524 if (grad[jq] > gmean) { p2[ncnew] = iq; ncnew++; }
01525 }
01526 }
01527
01528 counts[k] = ncnew;
01529 n2use += ncnew;
01530 }
01531 if (verbose > 2) printf("new total after g check %d\n", n2use);
01532
01533
01534 if (verbose > 2) printf("next new total (n2use) = %d,\n",n2use);
01535 xlimb = xlimbptr = malloc(sizeof(float) * n2use);
01536 ylimb = ylimbptr = malloc(sizeof(float) * n2use);
01537
01538 for (j=0;j<nfaint;j++) {
01539 k = indx[j];
01540 nc = counts[k];
01541 p2 = in4annulus[k];
01542 if (nc >0) {
01543 for (i=0;i<nc;i++) {
01544 iq = p2[i];
01545 jq = in2[iq];
01546 *xlimbptr++ = ixnann[jq];
01547 *ylimbptr++ = iynann[jq];
01548 }
01549 }
01550 free(p2);
01551 }
01552 free(in2); free(counts); free(values);
01553
01554
01555 t3 = systime();
01556 if (verbose > 0) printf("time for pre fit %8.3f\n", t3-t2);
01557 minihough(n2use, xlimb, ylimb, 30);
01558 free(xlimb); free(ylimb);
01559
01560 if (verbose > 0)
01561 printf("final sdisk_xc, sdisk_yc, sdisk_r = %g, %g, %g\n",sdisk_xc, sdisk_yc, sdisk_r);
01562 }
01563 t4 = systime();
01564 if (verbose > 0) printf("time for Hough %8.3f\n", t4-t3);
01565 free(theta3);
01566 free(indx);
01567 }
01568 free(grad); free(ang);
01569 tend = systime();
01570 if (verbose > 0) printf("total time %8.3f\n", tend-tstart);
01571 return 0;
01572 }