aboutsummaryrefslogtreecommitdiff
path: root/noao/digiphot/apphot/polyphot/apyfit.x
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /noao/digiphot/apphot/polyphot/apyfit.x
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'noao/digiphot/apphot/polyphot/apyfit.x')
-rw-r--r--noao/digiphot/apphot/polyphot/apyfit.x578
1 files changed, 578 insertions, 0 deletions
diff --git a/noao/digiphot/apphot/polyphot/apyfit.x b/noao/digiphot/apphot/polyphot/apyfit.x
new file mode 100644
index 00000000..abb76a6d
--- /dev/null
+++ b/noao/digiphot/apphot/polyphot/apyfit.x
@@ -0,0 +1,578 @@
+include <imhdr.h>
+include <mach.h>
+include "../lib/apphot.h"
+include "../lib/noise.h"
+include "../lib/polyphot.h"
+
+# AP_YFIT -- Procedure to compute the magnitude of an object inside a polygonal
+# aperture.
+
+int procedure ap_yfit (py, im, xver, yver, nver, skyval, skysig, nsky)
+
+pointer py # pointer to polyphot strucuture
+pointer im # pointer to IRAF image
+real xver[ARB] # x vertices coords
+real yver[ARB] # y vertices coords
+int nver # number of vertices
+real skyval # sky value
+real skysig # sigma of sky pixels
+int nsky # number of sky pixels
+
+double flux, area
+int noise, badpix, ier
+real datamin, datamax, mag, magerr, zmag, padu, itime, readnoise
+int apstati(), ap_yyfit(), ap_byyfit()
+real apstatr()
+
+begin
+ # Initialize.
+ call apsetd (py, PYFLUX, 0.0d0)
+ call apsetd (py, PYNPIX, 0.0d0)
+ call apsetr (py, PYMAG, INDEFR)
+ call apsetr (py, PYMAGERR, INDEFR)
+
+ # Compute the flux inside the polygon.
+ if (IS_INDEFR(apstatr (py, DATAMIN)) && IS_INDEFR(apstatr(py,
+ DATAMAX))) {
+ ier = ap_yyfit (im, xver, yver, nver, flux, area)
+ badpix = NO
+ } else {
+ if (IS_INDEFR(apstatr (py, DATAMIN)))
+ datamin = -MAX_REAL
+ else
+ datamin = apstatr (py, DATAMIN)
+ if (IS_INDEFR(apstatr (py, DATAMAX)))
+ datamax = MAX_REAL
+ else
+ datamax = apstatr (py, DATAMAX)
+ ier = ap_byyfit (im, xver, yver, nver, datamin, datamax, flux,
+ area, badpix)
+ }
+
+ if (ier == PY_NOPOLYGON)
+ return (PY_NOPOLYGON)
+ else if (ier == PY_NOPIX)
+ return (PY_NOPIX)
+
+ # Store the results.
+ call apsetd (py, PYFLUX, flux)
+ call apsetd (py, PYNPIX, area)
+ call apseti (py, PYBADPIX, badpix)
+
+ if (IS_INDEFR(skyval))
+ return (PY_NOSKYMODE)
+
+ # Get the photometry parameters.
+ zmag = apstatr (py, PYZMAG)
+ itime = apstatr (py, ITIME)
+ noise = apstati (py, NOISEFUNCTION)
+ padu = apstatr (py, EPADU)
+ readnoise = apstatr (py, READNOISE)
+
+ # Compute the magnitude and error.
+ if (badpix == NO) {
+ if (apstati (py, POSITIVE) == YES)
+ call apcopmags (flux, area, mag, magerr, 1, skyval,
+ skysig, nsky, zmag, noise, padu)
+ else
+ call apconmags (flux, area, mag, magerr, 1, skyval,
+ skysig, nsky, zmag, noise, padu, readnoise)
+ mag = mag + 2.5 * log10 (itime)
+
+ call apsetr (py, PYMAG, mag)
+ call apsetr (py, PYMAGERR, magerr)
+ }
+
+ return (ier)
+end
+
+
+# AP_YYFIT -- Measure the total flux inside a polygon.
+
+int procedure ap_yyfit (im, xver, yver, nver, flux, area)
+
+pointer im # pointer to IRAF image
+real xver[ARB] # x coordinates of the vertices
+real yver[ARB] # y coordinates of the vertices:
+int nver # number of vertices
+double flux # flux interior to the polygon
+double area # approximate area of polygon
+
+double fluxx, areax, fctnx, fctny
+real xmin, xmax, ymin, ymax, x1, x2, lx, ld
+pointer sp, work1, work2, xintr, buf
+int i, j, k, linemin, linemax, colmin, colmax, nintr, ier
+int ap_yclip()
+pointer imgl2r()
+
+begin
+ # Check that polygon has at least 3 vertices plus the closing vertex.
+ if (nver < 4) {
+ flux = INDEFD
+ area = 0.0d0
+ return (PY_NOPOLYGON)
+ }
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (work1, nver, TY_REAL)
+ call salloc (work2, nver, TY_REAL)
+ call salloc (xintr, nver, TY_REAL)
+
+ # Find the minimum and maximum x and y values of the polygon
+ # and detemine whether the polygon is partially off the image.
+
+ call alimr (xver, nver, xmin, xmax)
+ call alimr (yver, nver, ymin, ymax)
+ if (xmin < 0.5 || xmax > (IM_LEN(im,1) + 0.5) || ymin < 0.5 || ymax >
+ (IM_LEN(im,2) + 0.5))
+ ier = PY_OUTOFBOUNDS
+ else
+ ier = PY_OK
+
+ # Find the minimum and maximum image line numbers.
+ ymin = max (0.5, min (real (IM_LEN (im,2) + 0.5), ymin))
+ ymax = min (real (IM_LEN(im,2) + 0.5), max (0.5, ymax))
+ linemin = min (int (ymin + 0.5), int (IM_LEN(im,2)))
+ linemax = min (int (ymax + 0.5), int (IM_LEN(im,2)))
+
+ # Set up the line segment parameters and initialize fluxes and areas.
+ x1 = 0.5
+ x2 = IM_LEN(im,1) + 0.5
+ lx = x2 - x1
+ flux = 0.0d0
+ area = 0.0d0
+
+ # Loop over the range of lines of interest.
+ do i = linemin, linemax {
+
+ # Read in image line.
+ buf = imgl2r (im, i)
+ if (buf == EOF)
+ next
+
+ # Find all the x intersection points of image line and polygon.
+ if (ymin > i)
+ ld = min (i + 1, linemax)
+ else if (ymax < i)
+ ld = max (i - 1, linemin)
+ else
+ ld = i
+ nintr = ap_yclip (xver, yver, Memr[work1], Memr[work2],
+ Memr[xintr], nver, lx, ld)
+ if (nintr <= 0)
+ next
+ fctny = min (i + 0.5, ymax) - max (i - 0.5, ymin)
+
+ # Sort the x intersection points
+ call asrtr (Memr[xintr], Memr[xintr], nintr)
+
+ # Integrate the flux in each line segment.
+ fluxx = 0.0d0
+ areax = 0.0d0
+ do j = 1, nintr, 2 {
+
+ # Compute the line segment limits.
+ xmin = min (real (IM_LEN(im,1) + 0.5), max (0.5,
+ Memr[xintr+j-1]))
+ xmax = min (real (IM_LEN(im,1) + 0.5), max (0.5,
+ Memr[xintr+j]))
+ colmin = min (int (xmin + 0.5), int (IM_LEN(im,1)))
+ colmax = min (int (xmax + 0.5), int (IM_LEN(im,1)))
+
+ # Sum the contribution from a particular line segment.
+ do k = colmin, colmax {
+ fctnx = min (k + 0.5, xmax) - max (k - 0.5, xmin)
+ fluxx = fluxx + fctnx * Memr[buf+k-1]
+ areax = areax + fctnx
+ }
+ }
+
+ # Add the line sum to the total.
+ area = area + areax * fctny
+ flux = flux + fluxx * fctny
+ }
+
+ call sfree (sp)
+
+ # Return the appropriate error code.
+ if (area <= 0.0d0)
+ return (PY_NOPIX)
+ else if (ier != PY_OK)
+ return (ier)
+ else
+ return (PY_OK)
+end
+
+
+# AP_BYYFIT -- Measure the total flux inside a polygon while searching for
+# bad pixels at the same time.
+
+int procedure ap_byyfit (im, xver, yver, nver, datamin, datamax, flux, area,
+ badpix)
+
+pointer im # pointer to IRAF image
+real xver[ARB] # x coordinates of the vertices
+real yver[ARB] # y coordinates of the vertices:
+int nver # number of vertices
+real datamin # minimum good data value
+real datamax # maximum good data value
+double flux # flux interior to the polygon
+double area # approximate area of polygon
+int badpix # are there bad pixels
+
+int i, j, k, linemin, linemax, colmin, colmax, nintr, ier
+pointer sp, work1, work2, xintr, buf
+real xmin, xmax, ymin, ymax, x1, x2, lx, ld
+double fluxx, areax, fctnx, fctny
+int ap_yclip()
+pointer imgl2r()
+
+begin
+ # Check that polygon has at least 3 vertices plus a closing vertex.
+ if (nver < 4) {
+ flux = INDEFD
+ area = 0.0d0
+ badpix = NO
+ return (PY_NOPOLYGON)
+ }
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (work1, nver, TY_REAL)
+ call salloc (work2, nver, TY_REAL)
+ call salloc (xintr, nver, TY_REAL)
+
+ # Find minimum and maximum y values of the polygon vertices and
+ # compute the minimum and maximum image line limits.
+
+ call alimr (xver, nver, xmin, xmax)
+ call alimr (yver, nver, ymin, ymax)
+ if (xmin < 0.5 || xmax > (IM_LEN(im,1) + 0.5) || ymin < 0.5 || ymax >
+ (IM_LEN(im,2) + 0.5))
+ ier = PY_OUTOFBOUNDS
+ else
+ ier = PY_OK
+
+ # Find the min and max image line numbers.
+ ymin = max (0.5, min (real (IM_LEN (im,2) + 0.5), ymin))
+ ymax = min (real (IM_LEN(im,2) + 0.5), max (0.5, ymax))
+ linemin = max (1, min (int (ymin + 0.5), int (IM_LEN(im,2))))
+ linemax = max (1, min (int (ymax + 0.5), int (IM_LEN(im,2))))
+
+ # Set up line segment parameters and initialize fluxes.
+ x1 = 0.5
+ x2 = IM_LEN(im,1) + 0.5
+ lx = x2 - x1
+ flux = 0.0d0
+ area = 0.0d0
+
+ # Loop over the range of lines of interest.
+ badpix = NO
+ do i = linemin, linemax {
+
+ # Read in the image line.
+ buf = imgl2r (im, i)
+ if (buf == EOF)
+ next
+
+ # Find all the intersection points.
+ if (ymin > i)
+ ld = min (i + 1, linemax)
+ else if (ymax < i)
+ ld = max (i - 1, linemin)
+ else
+ ld = i
+ nintr = ap_yclip (xver, yver, Memr[work1], Memr[work2],
+ Memr[xintr], nver, lx, ld)
+ if (nintr <= 0)
+ next
+ fctny = min (i + 0.5, ymax) - max (i - 0.5, ymin)
+
+ # Sort the x intersection points
+ call asrtr (Memr[xintr], Memr[xintr], nintr)
+
+ # Integrate the flux in the line segment
+ fluxx = 0.0d0
+ areax = 0.0d0
+ do j = 1, nintr, 2 {
+
+ # Compute the line segment limits.
+ xmin = min (real (IM_LEN(im,1) + 0.5), max (0.5,
+ Memr[xintr+j-1]))
+ xmax = min (real (IM_LEN(im,1) + 0.5), max (0.5, Memr[xintr+j]))
+ colmin = min (int (xmin + 0.5), int (IM_LEN(im,1)))
+ colmax = min (int (xmax + 0.5), int (IM_LEN(im,1)))
+
+ # Sum the contribution from a particular line segment.
+ do k = colmin, colmax {
+ fctnx = min (k + 0.5, xmax) - max (k - 0.5, xmin)
+ fluxx = fluxx + fctnx * Memr[buf+k-1]
+ areax = areax + fctnx
+ if (Memr[buf+k-1] < datamin || Memr[buf+k-1] > datamax)
+ badpix = YES
+ }
+ }
+
+ # Add the line sum to the total.
+ area = area + areax * fctny
+ flux = flux + fluxx * fctny
+ }
+
+ call sfree (sp)
+
+ if (area <= 0.0d0)
+ return (PY_NOPIX)
+ if (badpix == YES)
+ return (PY_BADDATA)
+ else if (ier != PY_OK)
+ return (ier)
+ else
+ return (PY_OK)
+end
+
+
+# AP_YCLIP -- Compute the intersection of an image line with a polygon defined
+# by a list of vertices. The output is a list of ranges stored in the array
+# xranges. Two work additional work arrays xintr and slope are required for
+# the computation.
+
+int procedure ap_yclip (xver, yver, xintr, slope, xranges, nver, lx, ld)
+
+real xver[ARB] # x vertex coords
+real yver[ARB] # y vertex coords
+real xintr[ARB] # work array of x intersection points
+real slope[ARB] # work array of y slopes at intersection points
+real xranges[ARB] # x line segments
+int nver # number of vertices
+real lx, ld # equation of image line
+
+bool collinear
+int i, j, nintr, nplus, nzero, nneg, imin, imax, nadd
+real u1, u2, u1u2, dx, dy, dd, xa, wa
+
+begin
+ # Compute the intersection points of the image line and the polygon.
+ collinear = false
+ nplus = 0
+ nzero = 0
+ nneg = 0
+ nintr = 0
+ #u1 = - lx * yver[1] + ld
+ u1 = lx * (- yver[1] + ld)
+ do i = 2, nver {
+
+ #u2 = - lx * yver[i] + ld
+ u2 = lx * (- yver[i] + ld)
+ u1u2 = u1 * u2
+
+ # Does the polygon side intersect the image line ?
+ if (u1u2 <= 0.0) {
+
+
+ # Compute the x intersection coordinate if the point of
+ # intersection is not a vertex.
+
+ if ((u1 != 0.0) && (u2 != 0.0)) {
+
+ dy = yver[i-1] - yver[i]
+ dx = xver[i-1] - xver[i]
+ dd = xver[i-1] * yver[i] - yver[i-1] * xver[i]
+ #xa = (dx * ld - lx * dd)
+ xa = lx * (dx * ld - dd)
+ wa = dy * lx
+ nintr = nintr + 1
+ xranges[nintr] = xa / wa
+ slope[nintr] = -dy
+ if (slope[nintr] < 0.0)
+ nneg = nneg + 1
+ else if (slope[nintr] > 0.0)
+ nplus = nplus + 1
+ else
+ nzero = nzero + 1
+ collinear = false
+
+ # For each collinear line segment add two intersection
+ # points. Remove interior collinear intersection points.
+
+ } else if (u1 == 0.0 && u2 == 0.0) {
+
+ if (! collinear) {
+ nintr = nintr + 1
+ xranges[nintr] = xver[i-1]
+ if (i == 2)
+ slope[nintr] = yver[1] - yver[nver-1]
+ else
+ slope[nintr] = yver[i-1] - yver[i-2]
+ if (slope[nintr] < 0.0)
+ nneg = nneg + 1
+ else if (slope[nintr] > 0.0)
+ nplus = nplus + 1
+ else
+ nzero = nzero + 1
+ nintr = nintr + 1
+ xranges[nintr] = xver[i]
+ slope[nintr] = 0.0
+ nzero = nzero + 1
+ } else {
+ xranges[nintr] = xver[i]
+ slope[nintr] = 0.0
+ nzero = nzero + 1
+ }
+ collinear = true
+
+ # If the intersection point is a vertex add it to the
+ # list if it is not collinear with the next point. Add
+ # another point to the list if the vertex is at the
+ # apex of an acute angle.
+
+ } else if (u1 != 0.0) {
+
+ if (i == nver) {
+ dx = (xver[2] - xver[nver])
+ dy = (yver[2] - yver[nver])
+ dd = dy * (yver[nver-1] - yver[nver])
+ } else {
+ dx = (xver[i+1] - xver[i])
+ dy = (yver[i+1] - yver[i])
+ dd = dy * (yver[i-1] - yver[i])
+ }
+
+ # Test whether the point is collinear with the point
+ # ahead. If it is not include the intersection point.
+
+ if (dy != 0.0) {
+ nintr = nintr + 1
+ xranges[nintr] = xver[i]
+ slope[nintr] = yver[i] - yver[i-1]
+ if (slope[nintr] < 0.0)
+ nneg = nneg + 1
+ else if (slope[nintr] > 0.0)
+ nplus = nplus + 1
+ else
+ nzero = nzero + 1
+ }
+
+ # If the intersection point is an isolated vertex add
+ # another point to the list.
+
+ if (dd > 0.0) {
+ nintr = nintr + 1
+ xranges[nintr] = xver[i]
+ slope[nintr] = dy
+ if (slope[nintr] < 0.0)
+ nneg = nneg + 1
+ else if (slope[nintr] > 0.0)
+ nplus = nplus + 1
+ else
+ nzero = nzero + 1
+ }
+
+ collinear = false
+
+ } else
+ collinear = false
+ } else
+ collinear = false
+
+ u1 = u2
+ }
+
+ # Join up any split collinear line segments.
+ if (collinear && (slope[1] == 0.0)) {
+ xranges[1] = xranges[nintr-1]
+ slope[1] = slope[nintr-1]
+ nintr = nintr - 2
+ nzero = nzero - 2
+ }
+
+ # Return the number of intersection points if there are no interior
+ # collinear line segments.
+ if (nzero == 0 || nplus == 0 || nneg == 0)
+ return (nintr)
+
+ # Find the minimum and maximum intersection points.
+ call ap_alimr (xranges, nintr, u1, u2, imin, imax)
+
+ # Check for vertices at the ends of the ranges.
+
+ u1 = xranges[min(imin,imax)] - xranges[1]
+ u2 = xranges[nintr] - xranges[max(imin,imax)]
+
+ # Vertices were traversed in order of increasing x.
+ if ((u1 >= 0.0 && u2 > 0.0) || (u1 > 0.0 && u2 >= 0.0) ||
+ (u1 == u2 && imax > imin)) {
+ do i = imax + 1, nintr {
+ if (xranges[i] != xranges[i-1])
+ break
+ imax = i
+ }
+ do i = imin - 1, 1, -1 {
+ if (xranges[i] != xranges[i+1])
+ break
+ imin = i
+ }
+ }
+
+ # Vertices were traversed in order of decreasing x.
+ if ((u1 <= 0.0 && u2 < 0.0) || (u1 < 0.0 && u2 <= 0.0) ||
+ (u1 == u2 && imax < imin)) {
+ do i = imin + 1, nintr {
+ if (xranges[i] != xranges[i-1])
+ break
+ imin = i
+ }
+ do i = imax - 1, 1, -1 {
+ if (xranges[i] != xranges[i+1])
+ break
+ imax = i
+ }
+ }
+
+ # Reorder the x ranges and slopes if necessary.
+ if ((imax < imin) && ! (imin == nintr && imax == 1)) {
+ call amovr (xranges, xintr, nintr)
+ do i = 1, imax
+ xranges[nintr-imax+i] = xintr[i]
+ do i = imin, nintr
+ xranges[i-imax] = xintr[i]
+ call amovr (slope, xintr, nintr)
+ do i = 1, imax
+ slope[nintr-imax+i] = xintr[i]
+ do i = imin, nintr
+ slope[i-imax] = xintr[i]
+ } else if ((imin < imax) && ! (imin == 1 && imax == nintr)) {
+ call amovr (xranges, xintr, nintr)
+ do i = 1, imin
+ xranges[nintr-imin+i] = xintr[i]
+ do i = imax, nintr
+ xranges[i-imin] = xintr[i]
+ call amovr (slope, xintr, nintr)
+ do i = 1, imin
+ slope[nintr-imin+i] = xintr[i]
+ do i = imax, nintr
+ slope[i-imin] = xintr[i]
+ }
+
+ # Add any extra intersection points that are required to deal with
+ # the collinear line segments.
+
+ nadd = 0
+ for (i = 1; i <= nintr-2; ) {
+ if (slope[i] * slope[i+2] > 0.0) {
+ i = i + 2
+ } else {
+ nadd = nadd + 1
+ xranges[nintr+nadd] = xranges[i+1]
+ for (j = i + 3; j <= nintr; j = j + 1) {
+ if (slope[i] * slope[j] > 0)
+ break
+ nadd = nadd + 1
+ xranges[nintr+nadd] = xranges[j-1]
+ }
+ i = j
+ }
+ }
+
+ return (nintr + nadd)
+end