diff options
author | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
---|---|---|
committer | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
commit | 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch) | |
tree | 4464880c571602d54f6ae114729bf62a89518057 /noao/nproto/ace/split.x | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'noao/nproto/ace/split.x')
-rw-r--r-- | noao/nproto/ace/split.x | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/noao/nproto/ace/split.x b/noao/nproto/ace/split.x new file mode 100644 index 00000000..a0d564e4 --- /dev/null +++ b/noao/nproto/ace/split.x @@ -0,0 +1,625 @@ +include <pmset.h> +include <mach.h> +include "ace.h" +include "cat.h" +include "objs.h" +include "split.h" + + +# SPLIT - Split detected objects. +# +# Note that the sigma level map is modified and will be empty when done. + +procedure split (spt, cat, objmask, siglevel, siglevels, logfd) + +pointer spt #I Split parameters +pointer cat #U Catalog structure +pointer objmask #I Input and modified object mask +pointer siglevel #I Sigma level mask. +real siglevels[ARB] #I Sigma levels +int logfd #I Logfile + +int neighbors # Neighbor type +int dminpix # Minimum number of pixels for split object +int sminpix # Minimum number of split pixels +real sigavg # Minimum average above sky in sigma +real sigmax # Minimum peak above sky in sigma +real ssigavg # Minimum split average above sky in sigma +real ssigmax # Minimum split peak above sky in sigma +real splitmax # Maximum convolved sigma for splitting +real splitstep # Minimum split step in convolved sigma +real splitthresh # Transition convolved sigma + +int i, c, c1, c2, cs, clast, l, nc, nc1, nl +int level, nsobjs, navail, nalloc, nummax, val, num, pnum, oval, sval +long v[PM_MAXDIM] +real threshold +pointer sp, pnums, buf1, buf2, irl, orl, srl, outbuf, lastbuf +pointer objs, obj, splitmask, irlptr, orlptr, srlptr +pointer flags, ids, sobjs, links + +int andi(), ori() +bool pm_linenotempty() +pointer pm_create() + +begin + # Check for splitting map. + if (siglevel == NULL) + return + + # Set parameters. + call spt_pars ("open", "", spt) + + neighbors = SPT_NEIGHBORS(spt) + dminpix = SPT_MINPIX(spt) + sminpix = SPT_SMINPIX(spt) + sigavg = SPT_SIGAVG(spt) + sigmax = SPT_SIGPEAK(spt) + ssigavg = SPT_SSIGAVG(spt) + ssigmax = SPT_SSIGPEAK(spt) + splitmax = SPT_SPLITMAX(spt) + splitstep = SPT_SPLITSTEP(spt) + splitthresh = SPT_SPLITTHRESH(spt) + + if (logfd != NULL) { + call fprintf (logfd, " Split objects: sminpix = %d\n") + call pargi (sminpix) + } + + if (IS_INDEFR(splitmax)) + splitmax = MAX_REAL + + call pm_gsize (objmask, c, v, l) + splitmask = pm_create (c, v, l) + nc = v[1] + nl = v[2] + + call smark (sp) + call salloc (pnums, nc, TY_INT) + call salloc (buf1, nc+2, TY_INT) + call salloc (buf2, nc+2, TY_INT) + call salloc (irl, 3+3*nc, TY_INT) + call salloc (orl, 3+3*nc, TY_INT) + call salloc (srl, 3+3*nc, TY_INT) + + navail = 2 * CAT_NUMMAX(cat) + call calloc (ids, navail, TY_INT) + call calloc (links, navail, TY_INT) + call calloc (sobjs, navail, TY_POINTER) + nalloc = 0 + + # Go through sigma levels. + do level = 1, ARB { + + # Check if sigma value is in splitting range. + threshold = siglevels[level] + if (threshold == 0.) + next + if (threshold > splitmax) + break + + # Initialize flags. + nummax = CAT_NUMMAX(cat) + objs = CAT_OBJS(cat) + call calloc (flags, nummax+1, TY_SHORT) + do l = NUMSTART, nummax { + obj = Memi[objs+l-1] + if (obj == NULL) + next + if (SPLIT(obj) || SINGLE(obj)) + next + if (OBJ_NPIX(obj) < 2 * sminpix) { + SETFLAG (obj, OBJ_SINGLE) + next + } + Mems[flags+l] = 1 + } + + # Clear the mask. + call pm_clear (splitmask) + + outbuf = NULL + nsobjs = NUMSTART - 1 + do l = 1, nl { + v[1] = 1 + v[2] = l + if (!pm_linenotempty (siglevel, v)) { + outbuf = NULL + next + } + + lastbuf = outbuf + if (lastbuf == buf1) + outbuf = buf2 + else + outbuf = buf1 + + # Get sigma level mask. + call pmglri (siglevel, v, Memi[irl], 0, nc, 0) + + # Get parent object mask. Skip end regions not in siglev mask. + i = Memi[irl] - 1 + cs = Memi[irl+3] + nc1 = Memi[irl+3*i] + Memi[irl+3*i+1] - cs + v[1] = cs + call pmglpi (objmask, v, Memi[pnums], 0, nc1, 0) + v[1] = 1 + + # Initialize output range lists. + orlptr = orl; Memi[orlptr] = 0 + srlptr = srl + 3; sval = 0 + clast = 0 + + call aclri (Memi[outbuf], nc+2) + irlptr = irl + do i = 2, Memi[irl] { + irlptr = irlptr + 3 + val = Memi[irlptr+2] + if (val < level) + next + c1 = Memi[irlptr] + c2 = c1 + Memi[irlptr+1] - 1 + do c = c1, c2 { + pnum = Memi[pnums+c-cs] + if (MSPLIT(pnum)) + next + pnum = MNUM (pnum) + if (Mems[flags+pnum] == 0) + next + + if (lastbuf == NULL) + call sadd (c+1, l, Memi[outbuf], INDEFI, nc+2, + Memi[ids], Memi[links], Memi[sobjs], + nsobjs, nalloc, pnum, siglevels[val], + threshold, neighbors, num) + else + call sadd (c+1, l, Memi[outbuf], Memi[lastbuf], + nc+2, Memi[ids], Memi[links], Memi[sobjs], + nsobjs, nalloc, pnum, siglevels[val], + threshold, neighbors, num) + + if (nalloc == navail) { + navail = max (100*nalloc*(nl+1)/l/100, nalloc+10000) + call realloc (ids, navail, TY_INT) + call realloc (links, navail, TY_INT) + call realloc (sobjs, navail, TY_POINTER) + } + + # Update split object mask. + if (num != oval || c != clast) { + Memi[orlptr+1] = clast - Memi[orlptr] + orlptr = orlptr + 3 + + oval = num + Memi[orlptr] = c + Memi[orlptr+2] = oval + } + + # Update sigma level mask. + if (val != sval || c != clast) { + if (sval > level) { + Memi[srlptr+1] = clast - Memi[srlptr] + srlptr = srlptr + 3 + } + + sval = val + if (sval > level) { + Memi[srlptr] = c + Memi[srlptr+2] = sval + } + } + + clast = c + 1 + } + } + + # Update masks. + i = 1 + (orlptr - orl) / 3 + if (i > 1) { + Memi[orlptr+1] = clast - Memi[orlptr] + Memi[orl] = i + Memi[orl+1] = nc + call pmplri (splitmask, v, Memi[orl], 0, nc, PIX_SRC) + } + + if (sval > level) { + Memi[srlptr+1] = clast - Memi[srlptr] + Memi[srl] = 1 + (srlptr - srl) / 3 + } else + Memi[srl] = (srlptr - srl) / 3 + Memi[srl+1] = nc + call pmplri (siglevel, v, Memi[srl], 0, nc, PIX_SRC) + } + if (nsobjs < NUMSTART) + break + + if (threshold <= splitthresh) + call srenum (cat, objmask, splitmask, Memi[ids], Memi[sobjs], + nsobjs, dminpix, sigavg, sigmax) + else + call srenum (cat, objmask, splitmask, Memi[ids], Memi[sobjs], + nsobjs, sminpix, ssigavg, ssigmax) + + # Reuse object structures. + nsobjs = nalloc + nalloc = NUMSTART-1 + do i = NUMSTART-1, nsobjs-1 { + obj = Memi[sobjs+i] + if (obj != NULL) { + Memi[sobjs+nalloc] = Memi[sobjs+i] + nalloc = nalloc + 1 + } + } + + call mfree (flags, TY_SHORT) + } + + do i = 0, nalloc-1 + call mfree (Memi[sobjs+i], TY_POINTER) + call mfree (ids, TY_INT) + call mfree (links, TY_INT) + call mfree (sobjs, TY_POINTER) + + call pm_close (splitmask) + + call sfree (sp) +end + + +# SPLITADD -- Add a pixel to the object list and set the mask value. + +procedure sadd (c, l, z, zlast, nc, ids, links, objs, nobjs, nalloc, + pnum, data, threshold, neighbors, num) + +int c, l #I Pixel coordinate +int z[nc] #I Pixel values for current line +int zlast[nc] #I Pixel values for last line +int nc #I Number of pixels in a line +int ids[ARB] #I Mask ids +int links[ARB] #I Link to other mask ids with same number +int objs[ARB] #I Object numbers +int nobjs #U Number of objects +int nalloc #U Number of allocated objects +int pnum #I Parent number +real data #I Approximate (I(convolved) - sky) / sigma(convolved) +real threshold #I Threshold above sky in sigma units +int neighbors #I Neighbor type +int num #O Assigned mask value. + +int i, num1, c1, c2 +real val +bool merge +pointer obj, obj1 + +begin + # Inherit number of a neighboring pixel. + num = INDEFI + merge = false + if (neighbors == 4) { + c1 = c - 1 + c2 = c + if (IS_INDEFI(zlast[1])) { + if (z[c1] >= NUMSTART) + num = z[c1] + } else { + if (z[c1] >= NUMSTART) { + num = z[c1] + merge = true + } else if (zlast[c] >= NUMSTART) + num = ids[zlast[c]] + } + } else { + c1 = c - 1 + c2 = c + 1 + if (IS_INDEFI(zlast[1])) { + if (z[c1] >= NUMSTART) + num = z[c1] + } else { + if (z[c1] >= NUMSTART) { + num = z[c1] + merge = true + } else if (zlast[c1] >= NUMSTART) + num = ids[zlast[c1]] + else if (zlast[c] >= NUMSTART) + num = ids[zlast[c]] + else if (zlast[c2] >= NUMSTART) + num = ids[zlast[c2]] + } + } + + # If no number assign a new number. + if (num == INDEFI) { + nobjs = nobjs + 1 + num = nobjs + ids[num] = num + links[num] = 0 + if (nalloc < nobjs) { + call malloc (objs[num], OBJ_DETLEN, TY_STRUCT) + nalloc = nobjs + OBJ_FLAGS(objs[num]) = 0 + } + obj = objs[num] + OBJ_PNUM(obj) = pnum + OBJ_XAP(obj) = 0. + OBJ_YAP(obj) = 0. + OBJ_FLUX(obj) = 0. + OBJ_NPIX(obj) = 0 + OBJ_ISIGAVG(obj) = 0. + OBJ_ISIGMAX(obj) = 0. + } + obj = objs[num] + + # Merge overlapping objects from previous line. + if (merge) { + i = zlast[c2] + if (i >= NUMSTART && num != ids[i]) { + num1 = ids[i] + + obj1 = objs[num1] + OBJ_XAP(obj) = OBJ_XAP(obj) + OBJ_XAP(obj1) + OBJ_YAP(obj) = OBJ_YAP(obj) + OBJ_YAP(obj1) + OBJ_FLUX(obj) = OBJ_FLUX(obj) + OBJ_FLUX(obj1) + OBJ_NPIX(obj) = OBJ_NPIX(obj) + OBJ_NPIX(obj1) + OBJ_ISIGAVG(obj) = OBJ_ISIGAVG(obj) + OBJ_ISIGAVG(obj1) + OBJ_ISIGMAX(obj) = max (OBJ_ISIGMAX(obj), OBJ_ISIGMAX(obj1)) + + i = num + while (links[i] != 0) + i = links[i] + links[i] = num1 + repeat { + i = links[i] + ids[i] = num + } until (links[i] == 0) + + nalloc = nalloc + 1 + objs[nalloc] = obj1 + objs[num1] = NULL + } + } + + z[c] = num + OBJ_NPIX(obj) = OBJ_NPIX(obj) + 1 + val = data - threshold + OBJ_XAP(obj) = OBJ_XAP(obj) + val * c1 + OBJ_YAP(obj) = OBJ_YAP(obj) + val * l + OBJ_FLUX(obj) = OBJ_FLUX(obj) + val + OBJ_ISIGAVG(obj) = OBJ_ISIGAVG(obj) + val + OBJ_ISIGMAX(obj) = max (OBJ_ISIGMAX(obj), val) +end + + +# SRENUM -- Find detected pieces with a common parent and add to the +# catalog and the object mask. + +procedure srenum (cat, om, sm, ids, sobjs, nsobjs, minpix, + sigavg, sigmax) + +pointer cat #I Catalog structure +pointer om #I Object mask +pointer sm #I Split mask +int ids[nsobjs] #I Mask IDs +pointer sobjs[nsobjs] #U Input and output object list +int nsobjs #U Number of objects +int minpix #I Minimum number of pixels +real sigavg #I Cutoff of SIGAVG +real sigmax #I Cutoff of SIGMAX + +int i, j, n, nummax, nc, nl +real rval +pointer sp, nsplit, v, irl, srl, orl +pointer objs, obj, pobj +int ori() + +begin + nummax = CAT_NUMMAX(cat) + objs = CAT_OBJS(cat) + + call smark (sp) + call salloc (nsplit, nummax, TY_INT) + call aclri (Memi[nsplit], nummax) + + # Eliminate objects, by setting ids to zero, which don't satisfy + # the selection criteria (size, peak value, etc). Find objects + # that have split by counting, in the nsplit array, how many pieces + # belong to each parent. + + do i = NUMSTART, nsobjs { + obj = sobjs[i] + if (obj == NULL) + next + + n = OBJ_NPIX(obj) + rval = sqrt (real(n)) + OBJ_ISIGAVG(obj) = OBJ_ISIGAVG(obj) / rval + if (n < minpix || + (OBJ_ISIGMAX(obj) < sigmax && OBJ_ISIGAVG(obj) < sigavg)) { + ids[i] = 0 + next + } + + rval = OBJ_FLUX(obj) + if (rval > 0.) { + OBJ_XAP(obj) = OBJ_XAP(obj) / rval + OBJ_YAP(obj) = OBJ_YAP(obj) / rval + } else { + OBJ_XAP(obj) = INDEFR + OBJ_YAP(obj) = INDEFR + } + + n = OBJ_PNUM(obj) + Memi[nsplit+n-1] = Memi[nsplit+n-1] + 1 + } + + # Count objects that have a common parent (nsplit > 1) and assign + # new object numbers. Those not split are eliminated by setting + # ids to zero. Mark those unsplit objects whose parent objects + # are too small at the current size threshold as single to eliminate + # them from future attempts to split. + + j = nummax + do i = NUMSTART, nsobjs { + obj = sobjs[i] + if (obj == NULL || ids[i] == 0) + next + + n = OBJ_PNUM(obj) + if (Memi[nsplit+n-1] < 2) { + pobj = Memi[objs+n-1] + if (pobj != NULL) { + if (OBJ_NPIX(obj) < 2 * minpix) + SETFLAG (pobj, OBJ_SINGLE) + } + ids[i] = 0 + } else { + j = j + 1 + OBJ_NUM(obj) = j + nummax = nummax + 1 + } + } + + # If there are no split objects return. + if (nummax == CAT_NUMMAX(cat)) { + call sfree (sp) + return + } + + # Update the object mask for the split objects. + call salloc (v, PM_MAXDIM, TY_LONG) + call pm_gsize (om, i, Meml[v], j) + nc = Meml[v]; nl = Meml[v+1] + call salloc (irl, 3+3*nc, TY_INT) + call salloc (srl, 3+3*nc, TY_INT) + call salloc (orl, 3+3*nc, TY_INT) + + call srenum1 (om, sm, nc, nl, ids, sobjs, Memi[nsplit], + Meml[v], Memi[irl], Memi[srl], Memi[orl]) + + # Add split objects to catalog. Expand object structure. + call realloc (objs, nummax, TY_POINTER) + j = CAT_NUMMAX(cat) + do i = NUMSTART, nsobjs { + obj = sobjs[i] + if (obj == NULL || ids[i] == 0) + next + + call newobj (obj) + + sobjs[i] = NULL + Memi[objs+j] = obj + j = j + 1 + } + + # Set split flags for the split parent objects. + do i = NUMSTART, CAT_NUMMAX(cat)-1 { + obj = Memi[objs+i-1] + if (obj == NULL) + next + if (Memi[nsplit+i-1] > 1) + SETFLAG (obj, OBJ_SPLIT) + } + + # Update catalog info. + CAT_NOBJS(cat) = nummax + CAT_NUMMAX(cat) = nummax + CAT_OBJS(cat) = objs + + call sfree (sp) +end + + +procedure srenum1 (om, sm, nc, nl, ids, objs, nsplit, v, irl, srl, orl) + +pointer om #I Object mask pointer +pointer sm #I Split mask pointer +int nc, nl #I Dimensions +int ids[ARB] #I Mask IDs +pointer objs[ARB] #I Split objects +int nsplit[ARB] #I Number of split pieces +long v[PM_MAXDIM] #I Work array for line index +int irl[3,nc] #I Work array for input range list +int srl[3,nc] #I Work array for split range list +int orl[3,nc] #I Work array for output range list + +int i, j, k, l, n, c1, c2, sc1, id, sid, andi(), ori() + +begin + v[1] = 1 + do l = 1, nl { + v[2] = l + call pmglri (om, v, irl, 0, nc, 0) + call pmglri (sm, v, srl, 0, nc, 0) + + srl[1,srl[1,1]+1] = nc + 1 + sc1 = srl[1,2] + + j = 1 + k = 2 + do i = 2, irl[1,1] { + sid = irl[3,i] + id = MNUM(sid) + + # Unsplit object. + if (id < NUMSTART || nsplit[id] < 2) { + j = j + 1 + orl[1,j] = irl[1,i] + orl[2,j] = irl[2,i] + orl[3,j] = sid + next + } + + c1 = irl[1,i] + c2 = c1 + irl[2,i] - 1 + id = MSETFLAG (id, MASK_SPLIT) + + while (sc1 < c1) { + k = k + 1 + sc1 = srl[1,k] + } + + while (sc1 <= c2) { + sid = ids[srl[3,k]] + + # Check for split piece that was eliminated. + if (sid == 0) { + k = k + 1 + sc1 = srl[1,k] + next + } + sid = ids[sid] + if (sid == 0) { + k = k + 1 + sc1 = srl[1,k] + next + } + + # Add split piece to output. + if (sc1 > c1) { + j = j + 1 + orl[1,j] = c1 + orl[2,j] = sc1 - c1 + orl[3,j] = id + } + n = srl[2,k] + j = j + 1 + orl[1,j] = sc1 + orl[2,j] = n + orl[3,j] = OBJ_NUM(objs[sid]) + c1 = sc1 + n + + k = k + 1 + sc1 = srl[1,k] + } + + if (c1 <= c2) { + j = j + 1 + orl[1,j] = c1 + orl[2,j] = c2 - c1 + 1 + orl[3,j] = id + } + } + orl[1,1] = j + orl[2,1] = nc + call pmplri (om, v, orl, 0, nc, PIX_SRC) + } +end |