

# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <imhdr.h>
include <pkg/gtools.h>
include <error.h>
define MAXBUF (512*100) # Maximum number of pixels per block
# FIT1D -- Fit a function to image lines or columns and output an image
# consisting of the fit, the difference, or the ratio. The fitting parameters
# may be set interactively using the icfit package.
procedure t_fit1d ()
int listin # Input image list
int listout # Output image list
bool interactive # Interactive?
char sample[SZ_LINE] # Sample ranges
int naverage # Sample averaging size
char function[SZ_LINE] # Curve fitting function
int order # Order of curve fitting function
real low_reject, high_reject # Rejection thresholds
int niterate # Number of rejection iterations
real grow # Rejection growing radius
int axis # Image axis to fit
int ntype # Type of output
char input[SZ_LINE] # Input image
char output[SZ_FNAME] # Output image
pointer in, out # IMIO pointers
pointer ic # ICFIT pointer
pointer gt # GTOOLS pointer
bool same, clgetb()
int imtopen(), imtgetim(), imtlen(), strdic(), gt_init()
int clgeti()
real clgetr()
begin
# Get input and output lists and check that the number of images
# are the same.
call clgstr ("input", input, SZ_LINE)
listin = imtopen (input)
call clgstr ("output", input, SZ_LINE)
listout = imtopen (input)
if (imtlen (listin) != imtlen (listout)) {
call imtclose (listin)
call imtclose (listout)
call error (0, "Input and output image lists do not match")
}
# Get task parameters.
axis = clgeti ("axis")
call clgstr ("type", input, SZ_LINE)
call clgstr ("sample", sample, SZ_LINE)
naverage = clgeti ("naverage")
call clgstr ("function", function, SZ_LINE)
order = clgeti ("order")
low_reject = clgetr ("low_reject")
high_reject = clgetr ("high_reject")
niterate = clgeti ("niterate")
grow = clgetr ("grow")
interactive = clgetb ("interactive")
# Decode the output type and initialize the curve fitting package.
ntype = strdic (input, input, SZ_LINE, "|fit|difference|ratio|")
if (ntype == 0)
call error (0, "Unknown output type")
# Set the ICFIT pointer structure.
call ic_open (ic)
call ic_pstr (ic, "sample", sample)
call ic_puti (ic, "naverage", naverage)
call ic_pstr (ic, "function", function)
call ic_puti (ic, "order", order)
call ic_putr (ic, "low", low_reject)
call ic_putr (ic, "high", high_reject)
call ic_puti (ic, "niterate", niterate)
call ic_putr (ic, "grow", grow)
call ic_pstr (ic, "ylabel", "")
gt = gt_init()
call gt_sets (gt, GTTYPE, "line")
# Fit the lines in each input image.
while ((imtgetim (listin, input, SZ_LINE) != EOF) &&
(imtgetim (listout, output, SZ_FNAME) != EOF)) {
iferr (call f1d_immap (input, output, ntype, in, out, same)) {
call erract (EA_WARN)
next
}
call f1d_fit1d (in, out, ic, gt, input, axis, ntype, interactive)
call imunmap (in)
if (!same)
call imunmap (out)
}
call ic_closer (ic)
call gt_free (gt)
call imtclose (listin)
call imtclose (listout)
end
# F1D_FIT1D -- Given the image descriptor determine the fitting function
# for each line or column and create an output image. If the interactive flag
# is set then set the fitting parameters interactively.
procedure f1d_fit1d (in, out, ic, gt, title, axis, ntype, interactive)
pointer in # IMIO pointer for input image
pointer out # IMIO pointer for output image
pointer ic # ICFIT pointer
pointer gt # GTOOLS pointer
char title[ARB] # Title
int axis # Image axis to fit
int ntype # Type of output
bool interactive # Interactive?
char graphics[SZ_FNAME] # Graphics device
int i, nx, new
real div
pointer cv, gp, sp, x, wts, indata, outdata
int f1d_getline(), f1d_getdata(), strlen()
real cveval()
pointer gopen()
begin
# Error check.
if (IM_NDIM (in) > 2)
call error (0, "Image dimensions > 2 are not implemented")
if (axis > IM_NDIM (in))
call error (0, "Axis exceeds image dimension")
# Allocate memory for curve fitting.
nx = IM_LEN (in, axis)
call smark (sp)
call salloc (x, nx, TY_REAL)
call salloc (wts, nx, TY_REAL)
do i = 1, nx
Memr[x+i-1] = i
call amovkr (1., Memr[wts], nx)
call ic_putr (ic, "xmin", Memr[x])
call ic_putr (ic, "xmax", Memr[x+nx-1])
# If the interactive flag is set then use icg_fit to set the
# fitting parameters. Get_fitline returns EOF when the user
# is done. The weights are reset since the user may delete
# points.
if (interactive) {
call clgstr ("graphics", graphics, SZ_FNAME)
gp = gopen (graphics, NEW_FILE, STDGRAPH)
i = strlen (title)
indata = NULL
while (f1d_getline (ic, gt, in, axis, title, indata) != EOF) {
title[i + 1] = EOS
call icg_fit (ic, gp, "cursor", gt, cv, Memr[x], Memr[indata],
Memr[wts], nx)
call amovkr (1., Memr[wts], nx)
}
call mfree (indata, TY_REAL)
call gclose (gp)
}
# Loop through the input image and create an output image.
new = YES
while (f1d_getdata (in, out, axis, MAXBUF, indata, outdata) != EOF) {
call ic_fit (ic, cv, Memr[x], Memr[indata], Memr[wts],
nx, new, YES, new, new)
new = NO
# Be careful because the indata and outdata buffers may be the same.
switch (ntype) {
case 1:
call cvvector (cv, Memr[x], Memr[outdata], nx)
case 2:
do i = 0, nx-1
Memr[outdata+i] = Memr[indata+i] - cveval (cv, Memr[x+i])
case 3:
do i = 0, nx-1 {
div = cveval (cv, Memr[x+i])
if (abs (div) < 1E-20)
div = 1
Memr[outdata+i] = Memr[indata+i] / div
}
}
}
call cvfree (cv)
call sfree (sp)
end
# F1D_IMMAP -- Map images for fit1d.
procedure f1d_immap (input, output, ntype, in, out, same)
char input[ARB] # Input image
char output[ARB] # Output image
int ntype # Type of fit1d output
pointer in # Input IMIO pointer
pointer out # Output IMIO pointer
bool same # Same image?
int i
pointer sp, iroot, isect, oroot, osect, line, data
bool streq()
int imaccess(), impnlr()
pointer immap()
errchk immap
begin
# Get the root name and section of the input image.
call smark (sp)
call salloc (iroot, SZ_FNAME, TY_CHAR)
call salloc (isect, SZ_FNAME, TY_CHAR)
call salloc (oroot, SZ_FNAME, TY_CHAR)
call salloc (osect, SZ_FNAME, TY_CHAR)
call imgimage (input, Memc[iroot], SZ_FNAME)
call imgsection (input, Memc[isect], SZ_FNAME)
call imgimage (output, Memc[oroot], SZ_FNAME)
call imgsection (output, Memc[osect], SZ_FNAME)
same = streq (Memc[iroot], Memc[oroot])
# If the output image is not accessible then create it as a new copy
# of the full input image and initialize according to ntype.
if (imaccess (output, READ_WRITE) == NO) {
in = immap (Memc[iroot], READ_ONLY, 0)
out = immap (Memc[oroot], NEW_COPY, in)
IM_PIXTYPE(out) = TY_REAL
call salloc (line, IM_MAXDIM, TY_LONG)
call amovkl (long (1), Meml[line], IM_MAXDIM)
switch (ntype) {
case 1, 2:
while (impnlr (out, data, Meml[line]) != EOF)
call aclrr (Memr[data], IM_LEN(out, 1))
case 3:
while (impnlr (out, data, Meml[line]) != EOF)
call amovkr (1., Memr[data], IM_LEN(out, 1))
}
call imunmap (in)
call imunmap (out)
}
# Map the input and output images. If the output image has a section
# then use it. If the input image has a section and the output image
# does not then add the image section to the output image. Finally
# check the input and output images have the same size.
in = immap (input, READ_ONLY, 0)
if (Memc[isect] != EOS && Memc[osect] == EOS) {
call sprintf (Memc[osect], SZ_FNAME, "%s%s")
call pargstr (Memc[oroot])
call pargstr (Memc[isect])
} else
call strcpy (output, Memc[osect], SZ_FNAME)
if (streq (input, Memc[osect])) {
call imunmap (in)
in = immap (input, READ_WRITE, 0)
out = in
} else
out = immap (Memc[osect], READ_WRITE, 0)
do i = 1, IM_NDIM(in)
if (IM_LEN(in, i) != IM_LEN(out, i)) {
call imunmap (in)
if (!same)
call imunmap (out)
call sfree (sp)
call error (0, "Input and output images have different sizes")
}
call sfree (sp)
end
# F1D_GETDATA -- Get a line of image data.
int procedure f1d_getdata (in, out, axis, maxbuf, indata, outdata)
pointer in # Input IMIO pointer
pointer out # Output IMIO pointer
int axis # Image axis
int maxbuf # Maximum buffer size for column axis
pointer indata # Input data pointer
pointer outdata # Output data pointer
int i, index, last_index, col1, col2, nc, ncols, nlines, ncols_block
pointer inbuf, outbuf, ptr
pointer imgl1r(), impl1r(), imgl2r(), impl2r(), imgs2r(), imps2r()
data index/0/
begin
# Increment to the next image vector.
index = index + 1
# Initialize for the first vector.
if (index == 1) {
ncols = IM_LEN (in, 1)
if (IM_NDIM (in) == 1)
nlines = 1
else
nlines = IM_LEN (in, 2)
switch (axis) {
case 1:
last_index = nlines
case 2:
last_index = ncols
ncols_block = max (1, min (ncols, maxbuf / nlines))
col2 = 0
call malloc (indata, nlines, TY_REAL)
call malloc (outdata, nlines, TY_REAL)
}
}
# Finish up if the last vector has been done.
if (index > last_index) {
if (axis == 2) {
ptr = outbuf + index - 1 - col1
do i = 1, nlines {
Memr[ptr] = Memr[outdata+i-1]
ptr = ptr + nc
}
call mfree (indata, TY_REAL)
call mfree (outdata, TY_REAL)
}
index = 0
return (EOF)
}
# Get the next image vector.
switch (axis) {
case 1:
if (IM_NDIM (in) == 1) {
indata = imgl1r (in)
outdata = impl1r (out)
} else {
indata = imgl2r (in, index)
outdata = impl2r (out, index)
}
case 2:
if (index > 1) {
ptr = outbuf + index - 1 - col1
do i = 1, nlines {
Memr[ptr] = Memr[outdata+i-1]
ptr = ptr + nc
}
}
if (index > col2) {
col1 = col2 + 1
col2 = min (ncols, col1 + ncols_block - 1)
inbuf = imgs2r (in, col1, col2, 1, nlines)
outbuf = imps2r (out, col1, col2, 1, nlines)
nc = col2 - col1 + 1
}
ptr = inbuf + index - col1
do i = 1, nlines {
Memr[indata+i-1] = Memr[ptr]
ptr = ptr + nc
}
}
return (index)
end
# F1D_GETLINE -- Get image data to be fit interactively. Return EOF
# when the user enters EOF or CR. Default is 1 and the out of bounds
# requests are silently limited to the nearest in edge.
int procedure f1d_getline (ic, gt, im, axis, title, data)
pointer ic # ICFIT pointer
pointer gt # GTOOLS pointer
pointer im # IMIO pointer
int axis # Image axis
char title[ARB] # Title
pointer data # Image data
pointer x
char line[SZ_LINE]
int i, j, stat, imlen
int getline(), nscan()
pointer imgl1r()
data stat/EOF/
begin
# If the image is one dimensional do not prompt.
if (IM_NDIM (im) == 1) {
if (stat == EOF) {
call sprintf (title, SZ_LINE, "%s\n%s")
call pargstr (title)
call pargstr (IM_TITLE(im))
call gt_sets (gt, GTTITLE, title)
call mfree (data, TY_REAL)
call malloc (data, IM_LEN(im, 1), TY_REAL)
call amovr (Memr[imgl1r(im)], Memr[data], IM_LEN(im, 1))
stat = OK
} else
stat = EOF
return (stat)
}
# If the image is two dimensional prompt for the line or column.
switch (axis) {
case 1:
imlen = IM_LEN (im, 2)
call sprintf (title, SZ_LINE, "%s: Fit line =")
call pargstr (title)
case 2:
imlen = IM_LEN (im, 1)
call sprintf (title, SZ_LINE, "%s: Fit column =")
call pargstr (title)
}
call printf ("%s ")
call pargstr (title)
call flush (STDOUT)
if (getline(STDIN, line) == EOF)
return (EOF)
call sscan (line)
call gargi (i)
call gargi (j)
switch (nscan()) {
case 0:
stat = EOF
return (stat)
case 1:
i = max (1, min (imlen, i))
j = i
case 2:
i = max (1, min (imlen, i))
j = max (1, min (imlen, j))
}
call sprintf (title, SZ_LINE, "%s %d - %d\n%s")
call pargstr (title)
call pargi (i)
call pargi (j)
call pargstr (IM_TITLE(im))
call gt_sets (gt, GTTITLE, title)
switch (axis) {
case 1:
call ic_pstr (ic, "xlabel", "Column")
call xt_21imavg (im, axis, 1, IM_LEN(im, 1), i, j, x, data, imlen)
case 2:
call ic_pstr (ic, "xlabel", "Line")
call xt_21imavg (im, axis, i, j, 1, IM_LEN(im, 2), x, data, imlen)
}
call mfree (x, TY_REAL)
stat = OK
return (stat)
end
Source Code · Search Form · STSDAS
Maintained by the Science Software Group at STScI
This file last updated on 13 Jan 1997