/* @(#)iqefunc.c 14.3 (ESO-DMD) 04/27/00 11:25:31 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1996 European Southern Observatory .IDENT iqefunc.c .LANGUAGE C .AUTHOR P.Grosbol, IPG/ESO .KEYWORDS Image Quality Estimate, PSF .PURPOSE Routines for Image Quality Estimate holds iqe, iqebgv, iqemnt, iqesec, iqefit .VERSION 1.0 1995-Mar-16 : Creation, PJG .VERSION 1.1 1995-Jun-22 : Correct derivatives in 'g2efunc', PJG .VERSION 1.2 1996-Dec-03 : Code clean-up, PJG 000427 ------------------------------------------------------------------------*/ #include /* Standard ANSI-C library */ #include /* Mathematical definitions */ static double hsq2 = 0.7071067811865475244; /* constant 0.5*sqrt(2) */ #define MA 6 /* No. of variables */ #define MITER 64 /* Max. no. of iterations */ static float *pval; static float *pwght; static int mx, mp, winsize; static double w[9]; static double xi[9]; static double yi[9]; /* */ int iqe(pfm, pwm, mx, my, parm, sdev) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Estimate parameters for the Image Quality using a small frame around the object. The following parameters are estimated and given in the array 'parm': parm[0] = mean X position within array, first pixel = 0 parm[1] = FWHM in X parm[2] = mean Y position within array, first pixel = 0 parm[3] = FWHM in Y parm[4] = angle of major axis, degrees, along X = 0 parm[5] = peak value of object above background parm[6] = mean background level Further, estimates of the standard deviation of the parameters are given in 'sdev'. The routine is just a sequence of calls to 'iqebgv', 'iqemnt', 'iqesec' and 'iqefit'. .RETURN status, 0: OK, <0: estimate failed, ------------------------------------------------------------------------*/ float *pfm; float *pwm; int mx; int my; float *parm; float *sdev; { int n, err, nbg; int iqebgv(), iqemnt(), iqesec(), iqefit(); float bgv, bgs, s2f, r2d; float ap[6], cv[6], est[6], sec[6]; s2f = 2.0*sqrt(2.0*log(2.0)); /* Sigma to FWHM constant */ r2d = 45.0/atan(1.0); /* Radian to Degrees */ for (n=0; n<7; n++) parm[n] = sdev[n] = 0.0; winsize = (mx * my) - 1; /* size of sub window */ if ((err=iqebgv(pfm, pwm, mx, my, &bgv, &bgs, &nbg))) return -1; parm[6] = bgv; sdev[6] = bgs; if ((err=iqemnt(pfm, pwm, mx, my, bgv, bgs, est))) return -2; parm[0] = est[1]; parm[1] = s2f*est[2]; parm[2] = est[3]; parm[3] = s2f*est[4]; parm[5] = est[0]; if ((err=iqesec(pfm, pwm, mx, my, bgv, est, sec))) return -3; parm[4] = r2d*sec[5]; if ((err=iqefit(pfm, pwm, mx, my, bgv, sec, ap, cv))<0) return -4; parm[0] = ap[1]; sdev[0] = cv[1]; parm[1] = s2f*ap[2]; sdev[1] = s2f*cv[2]; parm[2] = ap[3]; sdev[2] = cv[3]; parm[3] = s2f*ap[4]; sdev[3] = s2f*cv[4]; parm[4] = fmod(r2d*ap[5]+180.0, 180.0); sdev[4] = r2d*cv[5]; if (sdev[4] > 180.) sdev[4] = 180.0; /* max is: Pi */ parm[5] = ap[0]; sdev[5] = cv[0]; return 0; } /* */ int iqebgv(pfm, pwm, mx, my, bgm, bgs, nbg) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Estimate background level for subimage .RETURN status, 0: OK, -1:no buffer space, -2: no points left ------------------------------------------------------------------------*/ float *pfm; float *pwm; int mx; int my; float *bgm; float *bgs; int *nbg; { int n, m, ns, ms, nt, mt; float *pfb, *pwb, *pf, *pw; float *pf0, *pf1, *pf2, *pf3, *pfs0, *pfs1, *pfs2, *pfs3; float *pw0, *pw1, *pw2, *pw3, *pws0, *pws1, *pws2, *pws3; double val, fks, ba, bm, bs; void hsort(); *bgm = 0.0; *bgs = 0.0; *nbg = 0; pfs0 = pfm; pfs1 = pfm + mx - 1; pfs2 = pfm + mx*(my-1); pfs3 = pfm + mx*my - 1; if (pwm) { pws0 = pwm; pws1 = pwm + mx - 1; pws2 = pwm + mx*(my-1); pws3 = pwm + mx*my - 1; } ns = (mx winsize)) return -99; if (pwm) pw = pwm + ioff; if ((!pwm) || (pwm && 0.0<*pw)) { val = *pf - bgv; am = val; ax = val*x; ay = val*y; axx = val*x*x; ayy = val*y*y; axy = val*x*y; nt++; } else am = ax = ay = axx = ayy = axy = 0.0; ki = ks = kn = 1; while (n--) { k = kn; if (!ki && ks==-1) { if (nx) nx = 0; else break; } ioff = (ki) ? ks : ks*mx; while (k--) { if (ki) x += ks; else y += ks; if (x<0.0 || y<0.0 || xm winsize)) break; if (pwm) pw += ioff; val = *pf - bgv; if ( (dv winsize)) break; dx = x - xc; dy = y - yc; r = sqrt(dx*dx + dy*dy); if (rl winsize)) return -99; pf = pfb; pw = pwb; iy = ny; if (pwm) { pwm += nxs + mx*nys; while (iy--) { ix = nx; while (ix--) { *pf++ = *pfm++ - bgv; psize = pfm - pfmo; if (psize > winsize) return -99; if (0.0<*pwm) *pw++ = *pwm++; else *pw++ = 1.0; } pfm += mx - nx; psize = pfm - pfmo; if ((psize < 0) || (psize > winsize)) return -99; pwm += mx - nx; } } else { while (iy--) { ix = nx; while (ix--) { *pf++ = *pfm++ - bgv; psize = pfm - pfmo; if (psize > winsize) return -99; *pw++ = 1.0; } pfm += mx - nx; psize = pfm - pfmo; if ((psize < 0) || (psize > winsize)) return -99; } } /* initialize parameters for fitting */ ap[0] = est[0]; ap[1] = est[1] - nxs; ap[2] = est[2]; ap[3] = est[3] - nys; ap[4] = est[4]; ap[5] = est[5]; /* perform actual 2D Gauss fit on small subimage */ n = g2efit(pfb, pwb, nx, ny, ap, cm, &chi); /* normalize parameters and uncertainties, and exit */ ap[1] += nxs; ap[3] += nys; free(pfb); return n; } /* */ int g2einit(val, wght, nx, ny) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Initiate gauss fit function, set pointers to data and weights .RETURN status, 0: OK, -1: error - bad pixel no. ------------------------------------------------------------------------*/ float *val; float *wght; int nx; int ny; { double fh, w1, w2, w3; if (nx<1) { /* if NO x-pixel set to NULL */ pval = (float *) 0; pwght = (float *) 0; mx = mp = 0; return -1; } pval = val; /* otherwise initiate static varables */ pwght = wght; mx = nx; mp = (0