diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/images/tv/imexamine/ierimexam.x | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/images/tv/imexamine/ierimexam.x')
-rw-r--r-- | pkg/images/tv/imexamine/ierimexam.x | 752 |
1 files changed, 752 insertions, 0 deletions
diff --git a/pkg/images/tv/imexamine/ierimexam.x b/pkg/images/tv/imexamine/ierimexam.x new file mode 100644 index 00000000..f76ff507 --- /dev/null +++ b/pkg/images/tv/imexamine/ierimexam.x @@ -0,0 +1,752 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> +include <gset.h> +include <math.h> +include <math/gsurfit.h> +include <math/nlfit.h> +include "imexam.h" + +define FITTYPES "|gaussian|moffat|" +define FITGAUSS 1 +define FITMOFFAT 2 + + +# IE_RIMEXAM -- Radial profile plot and photometry parameters. +# If no GIO pointer is given then only the photometry parameters are printed. +# First find the center using the marginal distributions. Then subtract +# a fit to the background. Compute the moments within the aperture and +# fit a gaussian of fixed center and zero background. Make the plot +# and print the photometry values. + +procedure ie_rimexam (gp, mode, ie, x, y) + +pointer gp +pointer ie +int mode +real x, y + +bool center, background, medsky, fitplot, clgpsetb() +real radius, buffer, width, magzero, rplot, beta, clgpsetr() +int nit, fittype, xorder, yorder, clgpseti(), strdic() + +int i, j, ns, no, np, nx, ny, npts, x1, x2, y1, y2 +int coordlen, plist[3], nplist, strlen() +real bkg, xcntr, ycntr, mag, e, pa, zcntr, wxcntr, wycntr +real params[3] +real fwhm, dbkg, dfwhm, gfwhm, efwhm +pointer sp, fittypes, title, coords, im, data, pp, ws, xs, ys, zs, gs, ptr, nl +double sumo, sums, sumxx, sumyy, sumxy +real r, r1, r2, r3, dx, dy, gseval(), amedr() +pointer clopset(), ie_gimage(), ie_gdata(), locpr() +extern ie_gauss(), ie_dgauss(), ie_moffat(), ie_dmoffat() +errchk stf_measure, nlinit, nlfit + +begin + call smark (sp) + call salloc (fittypes, SZ_FNAME, TY_CHAR) + call salloc (title, IE_SZTITLE, TY_CHAR) + call salloc (coords, IE_SZTITLE, TY_CHAR) + + iferr (im = ie_gimage (ie, NO)) { + call erract (EA_WARN) + call sfree (sp) + return + } + + # Open parameter set. + if (gp != NULL) { + if (IE_PP(ie) != NULL) + call clcpset (IE_PP(ie)) + } + pp = clopset ("rimexam") + + center = clgpsetb (pp, "center") + background = clgpsetb (pp, "background") + radius = clgpsetr (pp, "radius") + buffer = clgpsetr (pp, "buffer") + width = clgpsetr (pp, "width") + xorder = clgpseti (pp, "xorder") + yorder = clgpseti (pp, "yorder") + medsky = (xorder <= 0 || yorder <= 0) + nit = clgpseti (pp, "iterations") + + magzero = clgpsetr (pp, "magzero") + rplot = clgpsetr (pp, "rplot") + fitplot = clgpsetb (pp, "fitplot") + call clgpseta (pp, "fittype", Memc[fittypes], SZ_FNAME) + fittype = strdic (Memc[fittypes], Memc[fittypes], SZ_FNAME, FITTYPES) + if (fittype == 0) { + call eprintf ("WARNING: Unknown profile fit type `%s'.\n") + call pargstr (Memc[fittypes]) + call sfree (sp) + return + } + beta = clgpsetr (pp, "beta") + + # If the initial center is INDEF then use the previous value. + if (gp != NULL) { + if (!IS_INDEF(x)) + IE_X1(ie) = x + if (!IS_INDEF(y)) + IE_Y1(ie) = y + + xcntr = IE_X1(ie) + ycntr = IE_Y1(ie) + } else { + xcntr = x + ycntr = y + } + + # Center + if (center) + iferr (call ie_center (im, radius, xcntr, ycntr)) { + call erract (EA_WARN) + call sfree (sp) + return + } + + # Do the enclosed flux and direct FWHM measurments using the + # PSFMEASURE routines. + + call stf_measure (im, xcntr, ycntr, beta, 0.5, radius, nit, buffer, + width, INDEF, NULL, NULL, dbkg, r, dfwhm, gfwhm, efwhm) + if (fittype == FITGAUSS) + efwhm = gfwhm + + # Get data including a buffer and background annulus. + if (!background) { + buffer = 0. + width = 0. + } + r = max (rplot, radius + buffer + width) + x1 = xcntr - r + x2 = xcntr + r + y1 = ycntr - r + y2 = ycntr + r + iferr (data = ie_gdata (im, x1, x2, y1, y2)) { + call erract (EA_WARN) + call sfree (sp) + return + } + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + npts = nx * ny + + call salloc (xs, npts, TY_REAL) + call salloc (ys, npts, TY_REAL) + call salloc (ws, npts, TY_REAL) + + # Extract the background data if background subtracting. + ns = 0 + if (background && width > 0.) { + call salloc (zs, npts, TY_REAL) + + r1 = radius ** 2 + r2 = (radius + buffer) ** 2 + r3 = (radius + buffer + width) ** 2 + + ptr = data + do j = y1, y2 { + dy = (ycntr - j) ** 2 + do i = x1, x2 { + r = (xcntr - i) ** 2 + dy + if (r <= r1) + ; + else if (r >= r2 && r <= r3) { + Memr[xs+ns] = i + Memr[ys+ns] = j + Memr[zs+ns] = Memr[ptr] + ns = ns + 1 + } + ptr = ptr + 1 + } + } + } + + # Accumulate the various sums for the moments and the gaussian fit. + no = 0 + np = 0 + zcntr = 0. + sumo = 0.; sums = 0.; sumxx = 0.; sumyy = 0.; sumxy = 0. + ptr = data + gs = NULL + + if (ns > 0) { # Background subtraction + + # If background points are defined fit a surface and subtract + # the fitted background from within the object aperture. + + if (medsky) + bkg = amedr (Memr[zs], ns) + else { + repeat { + call gsinit (gs, GS_POLYNOMIAL, xorder, yorder, YES, + real (x1), real (x2), real (y1), real (y2)) + call gsfit (gs, Memr[xs], Memr[ys], Memr[zs], Memr[ws], ns, + WTS_UNIFORM, i) + if (i == OK) + break + xorder = max (1, xorder - 1) + yorder = max (1, yorder - 1) + call gsfree (gs) + } + bkg = gseval (gs, real(x1), real(y1)) + } + + do j = y1, y2 { + dy = j - ycntr + do i = x1, x2 { + dx = i - xcntr + r = sqrt (dx ** 2 + dy ** 2) + r3 = max (0., min (5., 2 * r / dfwhm - 1.)) + + if (medsky) + r2 = bkg + else { + r2 = gseval (gs, real(i), real(j)) + bkg = min (bkg, r2) + } + r1 = Memr[ptr] - r2 + + if (r <= radius) { + sumo = sumo + r1 + sums = sums + r2 + sumxx = sumxx + dx * dx * r1 + sumyy = sumyy + dy * dy * r1 + sumxy = sumxy + dx * dy * r1 + zcntr = max (r1, zcntr) + if (r <= rplot) { + Memr[xs+no] = r + Memr[ys+no] = r1 + Memr[ws+no] = exp (-r3**2) / max (.1, r**2) + no = no + 1 + } else { + np = np + 1 + Memr[xs+npts-np] = r + Memr[ys+npts-np] = r1 + Memr[ws+npts-np] = exp (-r3**2) / max (.1, r**2) + } + } else if (r <= rplot) { + np = np + 1 + Memr[xs+npts-np] = r + Memr[ys+npts-np] = r1 + } + ptr = ptr + 1 + } + } + + if (gs != NULL) + call gsfree (gs) + + } else { # No background subtraction + bkg = 0. + do j = y1, y2 { + dy = j - ycntr + do i = x1, x2 { + dx = i - xcntr + r = sqrt (dx ** 2 + dy ** 2) + r3 = max (0., min (5., 2 * r / dfwhm - 1.)) + r1 = Memr[ptr] + + if (r <= radius) { + sumo = sumo + r1 + sumxx = sumxx + dx * dx * r1 + sumyy = sumyy + dy * dy * r1 + sumxy = sumxy + dx * dy * r1 + zcntr = max (r1, zcntr) + if (r <= rplot) { + Memr[xs+no] = r + Memr[ys+no] = r1 + Memr[ws+no] = exp (-r3**2) / max (.1, r**2) + no = no + 1 + } else { + np = np + 1 + Memr[xs+npts-np] = r + Memr[ys+npts-np] = r1 + Memr[ws+npts-np] = exp (-r3**2) / max (.1, r**2) + } + } else if (r <= rplot) { + np = np + 1 + Memr[xs+npts-np] = r + Memr[ys+npts-np] = r1 + } + ptr = ptr + 1 + } + } + } + if (np > 0) { + call amovr (Memr[xs+npts-np], Memr[xs+no], np) + call amovr (Memr[ys+npts-np], Memr[ys+no], np) + call amovr (Memr[ws+npts-np], Memr[ws+no], np) + } + if (rplot <= radius) { + no = no + np + np = no - np + } else + np = no + np + + + # Compute the photometry and profile fit parameters. + + switch (fittype) { + case FITGAUSS: + plist[1] = 1 + plist[2] = 2 + nplist = 2 + params[2] = dfwhm**2 / (8 * log(2.)) + params[1] = zcntr + call nlinitr (nl, locpr (ie_gauss), locpr (ie_dgauss), + params, params, 2, plist, nplist, .001, 100) + call nlfitr (nl, Memr[xs], Memr[ys], Memr[ws], no, 1, WTS_USER, i) + if (i == SINGULAR || i == NO_DEG_FREEDOM) { + call eprintf ("WARNING: Gaussian fit did not converge\n") + call tsleep (5) + zcntr = INDEF + fwhm = INDEF + } else { + call nlpgetr (nl, params, i) + if (params[2] < 0.) { + zcntr = INDEF + fwhm = INDEF + } else { + zcntr = params[1] + fwhm = sqrt (8 * log (2.) * params[2]) + } + } + case FITMOFFAT: + plist[1] = 1 + plist[2] = 2 + if (IS_INDEF(beta)) { + params[3] = -3.0 + plist[3] = 3 + nplist = 3 + } else { + params[3] = -beta + nplist = 2 + } + params[2] = dfwhm / 2. / sqrt (2.**(-1./params[3]) - 1.) + params[1] = zcntr + call nlinitr (nl, locpr (ie_moffat), locpr (ie_dmoffat), + params, params, 3, plist, nplist, .001, 100) + call nlfitr (nl, Memr[xs], Memr[ys], Memr[ws], no, 1, WTS_USER, i) + if (i == SINGULAR || i == NO_DEG_FREEDOM) { + call eprintf ("WARNING: Moffat fit did not converge\n") + call tsleep (5) + zcntr = INDEF + fwhm = INDEF + beta = INDEF + } else { + call nlpgetr (nl, params, i) + if (params[2] < 0.) { + zcntr = INDEF + fwhm = INDEF + beta = INDEF + } else { + zcntr = params[1] + beta = -params[3] + fwhm = abs (params[2])*2.*sqrt (2.**(-1./params[3]) - 1.) + } + } + } + + mag = INDEF + r = INDEF + e = INDEF + pa = INDEF + if (sumo > 0.) { + mag = magzero - 2.5 * log10 (sumo) + r2 = sumxx + sumyy + if (r2 > 0.) { + switch (fittype) { + case FITGAUSS: + r = 2 * sqrt (log (2.) * r2 / sumo) + case FITMOFFAT: + if (beta > 2.) + r = 2 * sqrt ((beta-2.)*(2.**(1./beta)-1) * r2 / sumo) + } + r1 =(sumxx-sumyy)**2+(2*sumxy)**2 + if (r1 > 0.) + e = sqrt (r1) / r2 + else + e = 0. + } + if (e < 0.01) + e = 0. + else + pa = RADTODEG (0.5 * atan2 (2*sumxy, sumxx-sumyy)) + } + + call ie_mwctran (ie, xcntr, ycntr, wxcntr, wycntr) + if (xcntr == wxcntr && ycntr == wycntr) + call strcpy ("%.2f %.2f", Memc[title], IE_SZTITLE) + else { + call sprintf (Memc[title], IE_SZTITLE, "%s %s") + if (IE_XFORMAT(ie) == '%') + call pargstr (IE_XFORMAT(ie)) + else + call pargstr ("%g") + if (IE_YFORMAT(ie) == '%') + call pargstr (IE_YFORMAT(ie)) + else + call pargstr ("%g") + } + call sprintf (Memc[coords], IE_SZTITLE, Memc[title]) + call pargr (wxcntr) + call pargr (wycntr) + + # Plot the radial profile and overplot the gaussian fit. + if (gp != NULL) { + call sprintf (Memc[title], IE_SZTITLE, + "%s: Radial profile at %s\n%s") + call pargstr (IE_IMNAME(ie)) + call pargstr (Memc[coords]) + call pargstr (IM_TITLE(im)) + + call ie_graph (gp, mode, pp, Memc[title], Memr[xs], Memr[ys], + np, "", "") + + if (fitplot && !IS_INDEF (fwhm)) { + np = 51 + dx = rplot / (np - 1) + do i = 0, np - 1 + Memr[xs+i] = i * dx + call nlvectorr (nl, Memr[xs], Memr[ys], np, 1) + call gseti (gp, G_PLTYPE, 2) + call gpline (gp, Memr[xs], Memr[ys], np) + call gseti (gp, G_PLTYPE, 1) + } + call gseti (gp, G_PLTYPE, 2) + + call printf ("%6.2f %6.2f %7.4g %7.4g %7.4g %4.2f %4d") + call pargr (radius) + call pargr (mag) + call pargd (sumo) + call pargd (sums / no) + call pargr (zcntr) + call pargr (e) + call pargr (pa) + switch (fittype) { + case FITGAUSS: + call printf (" %4w %8.2f %8.2f %6.2f\n") + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + case FITMOFFAT: + call printf (" %4.2f %8.2f %8.2f %6.2f\n") + call pargr (beta) + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + } + + } else { + if (IE_LASTKEY(ie) != 'a') { + coordlen = max (11, strlen (Memc[coords])) + call printf ("# %5s %7s %-*s\n# %5s %6s %7s %7s %7s %4s %4s") + call pargstr ("COL") + call pargstr ("LINE") + call pargi (coordlen) + call pargstr ("COORDINATES") + call pargstr ("R") + call pargstr ("MAG") + call pargstr ("FLUX") + call pargstr ("SKY") + call pargstr ("PEAK") + call pargstr ("E") + call pargstr ("PA") + switch (fittype) { + case FITGAUSS: + call printf (" %4w %8s %8s %6s\n") + call pargstr ("ENCLOSED") + call pargstr ("GAUSSIAN") + call pargstr ("DIRECT") + case FITMOFFAT: + call printf (" %4s %8s %8s %6s\n") + call pargstr ("BETA") + call pargstr ("ENCLOSED") + call pargstr ("MOFFAT") + call pargstr ("DIRECT") + } + } + + call printf ( + "%7.2f %7.2f %-*s\n %6.2f %6.2f %7.4g %7.4g %7.4g %4.2f %4d") + call pargr (xcntr) + call pargr (ycntr) + call pargi (coordlen) + call pargstr (Memc[coords]) + call pargr (radius) + call pargr (mag) + call pargd (sumo) + call pargd (sums / no) + call pargr (zcntr) + call pargr (e) + call pargr (pa) + switch (fittype) { + case FITGAUSS: + call printf (" %4w %8.2f %8.2f %6.2f\n") + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + case FITMOFFAT: + call printf (" %4.2f %8.2f %8.2f %6.2f\n") + call pargr (beta) + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + } + } + + if (IE_LOGFD(ie) != NULL) { + if (IE_LASTKEY(ie) != 'a') { + coordlen = max (11, strlen (Memc[coords])) + call fprintf (IE_LOGFD(ie), + "# %5s %7s %-*s %6s %6s %7s %7s %7s %4s %4s") + call pargstr ("COL") + call pargstr ("LINE") + call pargi (coordlen) + call pargstr ("COORDINATES") + call pargstr ("R") + call pargstr ("MAG") + call pargstr ("FLUX") + call pargstr ("SKY") + call pargstr ("PEAK") + call pargstr ("E") + call pargstr ("PA") + switch (fittype) { + case FITGAUSS: + call fprintf (IE_LOGFD(ie), " %4w %8s %8s %6s\n") + call pargstr ("ENCLOSED") + call pargstr ("GAUSSIAN") + call pargstr ("DIRECT") + case FITMOFFAT: + call fprintf (IE_LOGFD(ie), " %4s %8s %8s %6s\n") + call pargstr ("BETA") + call pargstr ("ENCLOSED") + call pargstr ("MOFFAT") + call pargstr ("DIRECT") + } + } + + call fprintf (IE_LOGFD(ie), + "%7.2f %7.2f %-*s %6.2f %6.2f %7.4g %7.4g %7.4g %4.2f %4d") + call pargr (xcntr) + call pargr (ycntr) + call pargi (coordlen) + call pargstr (Memc[coords]) + call pargr (radius) + call pargr (mag) + call pargd (sumo) + call pargd (sums / no) + call pargr (zcntr) + call pargr (e) + call pargr (pa) + switch (fittype) { + case FITGAUSS: + call fprintf (IE_LOGFD(ie), " %4w %8.2f %8.2f %6.2f\n") + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + case FITMOFFAT: + call fprintf (IE_LOGFD(ie), " %4.2f %8.2f %8.2f %6.2f\n") + call pargr (beta) + call pargr (efwhm) + call pargr (fwhm) + call pargr (dfwhm) + } + } + + if (gp == NULL) + call clcpset (pp) + else + IE_PP(ie) = pp + + call nlfreer (nl) + call sfree (sp) +end + + +# IE_CENTER -- Find the center of gravity from the marginal distributions. + +procedure ie_center (im, radius, xcntr, ycntr) + +pointer im +real radius +real xcntr, ycntr + +int i, j, k, x1, x2, y1, y2, nx, ny, npts +real xlast, ylast +real mean, sum, sum1, sum2, sum3, asumr() +pointer data, ptr, ie_gdata() +errchk ie_gdata + +begin + # Find the center of a star image given approximate coords. Uses + # Mountain Photometry Code Algorithm as outlined in Stellar Magnitudes + # from Digital Images. + + do k = 1, 3 { + # Extract region around center + xlast = xcntr + ylast = ycntr + x1 = xcntr - radius + 0.5 + x2 = xcntr + radius + 0.5 + y1 = ycntr - radius + 0.5 + y2 = ycntr + radius + 0.5 + data = ie_gdata (im, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + npts = nx * ny + + # Find center of gravity for marginal distributions above mean. + sum = asumr (Memr[data], npts) + mean = sum / nx + sum1 = 0. + sum2 = 0. + + do i = x1, x2 { + ptr = data + i - x1 + sum3 = 0. + do j = y1, y2 { + sum3 = sum3 + Memr[ptr] + ptr = ptr + nx + } + sum3 = sum3 - mean + if (sum3 > 0.) { + sum1 = sum1 + i * sum3 + sum2 = sum2 + sum3 + } + } + xcntr = sum1 / sum2 + + ptr = data + mean = sum / ny + sum1 = 0. + sum2 = 0. + do j = y1, y2 { + sum3 = 0. + do i = x1, x2 { + sum3 = sum3 + Memr[ptr] + ptr = ptr + 1 + } + sum3 = sum3 - mean + if (sum3 > 0.) { + sum1 = sum1 + j * sum3 + sum2 = sum2 + sum3 + } + } + ycntr = sum1 / sum2 + + if (int(xcntr) == int(xlast) && int(ycntr) == int(ylast)) + break + } +end + + +# IE_GAUSS -- Gaussian function used in NLFIT. The parameters are the +# amplitude and sigma squared and the input variable is the radius. + +procedure ie_gauss (x, nvars, p, np, z) + +real x[nvars] #I Input variables +int nvars #I Number of variables +real p[np] #I Parameter vector +int np #I Number of parameters +real z #O Function return + +real r2 + +begin + r2 = x[1]**2 / (2 * p[2]) + if (abs (r2) > 20.) + z = 0. + else + z = p[1] * exp (-r2) +end + + +# IE_DGAUSS -- Gaussian function and derivatives used in NLFIT. The parameters +# are the amplitude and sigma squared and the input variable is the radius. + +procedure ie_dgauss (x, nvars, p, dp, np, z, der) + +real x[nvars] #I Input variables +int nvars #I Number of variables +real p[np] #I Parameter vector +real dp[np] #I Dummy array of parameters increments +int np #I Number of parameters +real z #O Function return +real der[np] #O Derivatives + +real r2 + +begin + r2 = x[1]**2 / (2 * p[2]) + if (abs (r2) > 20.) { + z = 0. + der[1] = 0. + der[2] = 0. + } else { + der[1] = exp (-r2) + z = p[1] * der[1] + der[2] = z * r2 / p[2] + } +end + + +# IE_MOFFAT -- Moffat function used in NLFIT. The parameters are the +# amplitude, alpha squared, and beta and the input variable is the radius. + +procedure ie_moffat (x, nvars, p, np, z) + +real x[nvars] #I Input variables +int nvars #I Number of variables +real p[np] #I Parameter vector +int np #I Number of parameters +real z #O Function return + +real y + +begin + y = 1 + (x[1] / p[2]) ** 2 + if (abs (y) > 20.) + z = 0. + else + z = p[1] * y ** p[3] +end + + +# IE_DMOFFAT -- Moffat function and derivatives used in NLFIT. The parameters +# are the amplitude, alpha squared, and beta and the input variable is the +# radius. + +procedure ie_dmoffat (x, nvars, p, dp, np, z, der) + +real x[nvars] #I Input variables +int nvars #I Number of variables +real p[np] #I Parameter vector +real dp[np] #I Dummy array of parameters increments +int np #I Number of parameters +real z #O Function return +real der[np] #O Derivatives + +real y + +begin + y = 1 + (x[1] / p[2]) ** 2 + if (abs (y) > 20.) { + z = 0. + der[1] = 0. + der[2] = 0. + der[3] = 0. + } else { + der[1] = y ** p[3] + z = p[1] * der[1] + der[2] = -2 * z / y * p[3] / p[2] * (x[1] / p[2]) ** 2 + der[3] = z * log (y) + } +end |