aboutsummaryrefslogtreecommitdiff
path: root/noao/imred/generic
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /noao/imred/generic
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'noao/imred/generic')
-rw-r--r--noao/imred/generic/Revisions220
-rw-r--r--noao/imred/generic/background.cl6
-rw-r--r--noao/imred/generic/background.par16
-rw-r--r--noao/imred/generic/darksub.cl99
-rw-r--r--noao/imred/generic/doc/Spelldict51
-rw-r--r--noao/imred/generic/doc/background.hlp82
-rw-r--r--noao/imred/generic/doc/darksub.hlp60
-rw-r--r--noao/imred/generic/doc/flat1d.hlp157
-rw-r--r--noao/imred/generic/doc/flatten.hlp42
-rw-r--r--noao/imred/generic/doc/normalize.hlp45
-rw-r--r--noao/imred/generic/doc/normflat.hlp54
-rw-r--r--noao/imred/generic/flat1d.par17
-rw-r--r--noao/imred/generic/flat1d.x478
-rw-r--r--noao/imred/generic/flatten.cl64
-rw-r--r--noao/imred/generic/flatten.par13
-rw-r--r--noao/imred/generic/generic.cl17
-rw-r--r--noao/imred/generic/generic.hd11
-rw-r--r--noao/imred/generic/generic.men6
-rw-r--r--noao/imred/generic/generic.par5
-rw-r--r--noao/imred/generic/mkpkg54
-rw-r--r--noao/imred/generic/normalize.cl79
-rw-r--r--noao/imred/generic/normflat.cl69
-rw-r--r--noao/imred/generic/normflat.par15
-rw-r--r--noao/imred/generic/x_generic.x1
24 files changed, 1661 insertions, 0 deletions
diff --git a/noao/imred/generic/Revisions b/noao/imred/generic/Revisions
new file mode 100644
index 00000000..7ae1bfa5
--- /dev/null
+++ b/noao/imred/generic/Revisions
@@ -0,0 +1,220 @@
+.help revisions Jun88 noao.imred.generic
+.nf
+
+generic$generic.cl
+generic$generic.men
+generic$cosmicrays.par -
+ Removed the cosmicrays task which is now in crutil. (6/12/02, Valdes)
+
+=====
+V2.12
+=====
+
+generic$mkpkg
+ Added missing <error.h> dependency for flat1d.x (12/13/01, MJF)
+
+generic$normalize.cl
+generic$normalize.par -
+ Rewrote as modern cl procedure script with possiblity to extend to
+ MEF extensions. (5/13/99, Valdes)
+
+generic$flatten.cl
+generic$normalize.cl
+ Changed use of FILES for image list expansion to SECTIONS.
+ (5/13/99, Valdes)
+
+=======
+V2.11.1
+=======
+
+generic$normalize.cl
+generic$normflat.cl
+ Added CCDMEAN = 1 to final image header. (4/16/93, Valdes)
+
+generic$flat1d.x
+generic$doc/flat1d.hlp
+ CCDMEAN is set to 1. (3/15/93, Valdes)
+
+=======
+V2.10.2
+=======
+=======
+V2.10.1
+=======
+=======
+V2.10.0
+=======
+=====
+V2.10
+=====
+generic$flatten.par
+ Changed the default values of the keeplog and logfile parameters from
+ ")_.keeplog" and ")_.logfile" to ")generic.keeplog" and ")generic.logfile"
+ respectively. This change avoids a parameter redirection in the irred
+ package. (8/26/91 LED)
+
+generic$darksub.cl
+ Included all parameters in IMARITH calls due to complaint about title
+ being changed. (12/9/91)
+
+====
+V2.9
+====
+
+generic$normalize.cl
+generic$normflat.cl
+generic$normalize.par
+generic$normflat.par
+ Modified use of IMSTATISTICS for additional fields parameter. If the
+ user redefined the defaults for IMSTAT then NORMALIZE and NORMFLAT
+ will fail. (11/30/89, Valdes)
+
+generic$flatten.par
+generic$normalize.par
+generic$normflat.par
+ Change parameter reference from )generic. to )_. to allow defining
+ tasks in other packages.
+
+generic$darksub.cl
+ The last change caused the nscan to have the wrong value causing an
+ improper error (exposure time for ... not found). The value of nscan()
+ is now saved before scanning the output list which must be done before
+ any error breaks to avoid out of sync lists. (7/1/88 Valdes)
+
+generic$darksub.cl
+ The fscan on the output list must immediately follow the fscan on the
+ input list to prevent the lists getting out of sync. (2/4/88 Valdes)
+
+generic$cosmicrays.par +
+generic$generic.cl
+generic$generic.men
+ Added link to COSMICRAY program in CCDRED. (12/11/87 Valdes)
+
+====
+V2.5
+====
+
+====
+V2.3
+====
+
+generic$flat1d.x: Valdes, July 3, 1986
+ 1. FLAT1D modified to use new ICFIT package.
+
+=========================================
+STScI Pre-release and 1st SUN 2.3 Release
+=========================================
+
+generic$darksub.cl: Valdes, April 8, 1986
+ 1. DARKSUB rewritten to use exposure times from the image headers and
+ to allow input and output images.
+
+===========
+Release 2.2
+===========
+
+From Valdes Feb 12, 1986:
+
+1. The GENERIC package script was inadvertently defining CMDSTR which
+was moved to the SYSTEM package. This caused MKSCRIPT to fail if
+and only if GENERIC was loaded. This has now been fixed.
+------
+From Valdes Feb 10, 1986:
+
+1. The scripts DARKSUB, NORMFLAT, and NORMALIZE have been changed so
+that calls to IMCOPY have VERBOSE=NO when dealing with temporary images.
+Previously, output from imcopy was being printed but, of course, the
+temporary image filenames were meaningless to the user.
+------
+From Valdes Nov 7, 1985:
+
+1. The generally useful task MKSCRIPT has been moved to the system
+package.
+------
+From Valdes Nov 1, 1985:
+
+1. A general image reduction tool for creating command scripts has
+been added. The task is called MKSCRIPT. See the help page for
+this task. An improved version of this task may eventually replace
+MKSCRIPT as a system task. (As a technical detail a hidden task CMDSTR
+used by MKSCRIPT has also been added)
+------
+From Valdes Oct 17, 1985:
+
+1. Flat1d and background now allow averaging of image lines or columns
+when interactively setting the fitting parameters. The syntax is
+"Fit line = 10 30"; i.e. blank separated line or column numbers. A
+single number selects just one line or column. Be aware however, that
+the actual fitting of the image is still done on each column or line
+individually.
+
+2. The zero line in the interactive curve fitting graphs has been removed.
+This zero line interfered with fitting data near zero.
+------
+From Valdes Oct 4, 1985:
+
+1. Flat1d and background modified to allow lower and upper rejection
+limits and rejection iteration. This means the parameter file has changed.
+------
+From Valdes Oct 1, 1985:
+
+1. Task revisions renamed to revs.
+-----
+From Valdes on August 26, 1985:
+
+1. Flat1d was modified to eliminate fitting of lines or columns in which
+all the data is below minflat. Also if all the data is greater than minflat
+then the ratio is computed without checking each data point which is more
+efficient (particularly with the vector operators). Thus, flat1d should
+be somewhat faster; particularly for applications like multi-slits where
+many parts of the data are less than minflat.
+
+------
+From Valdes on August 7, 1985:
+
+1. Flat1d and background have new parameters to select the graphics
+output device and the graphics cursor input.
+
+2. Flat1d and background (fit1d) have been recompiled to use the "improved"
+icfit and gtools packages.
+
+------
+From Valdes on July 26, 1985:
+
+1. Help page available for flat1d.
+
+2. Background has been modified to use new fit1d task. It now does
+column backgrounds without transposes and allows image sections.
+
+------
+From Valdes on July 25, 1985:
+
+1. A new task called flat1d replaces lineflat and colflat. It is
+essentially the same as lineflat except for an extra parameter "axis"
+which selects the axis along which the 1D functions are to be fit.
+Axis 1 is lines and axis 2 is columns. The advantages of this change are:
+
+ a. Column fitting is done without transposing the image.
+ b. The colflat script using image transpositions would not
+ work the same as lineflat when used with sections. Now
+ it is possible to mosaic several flat fields as need with
+ multiple slits or apertures.
+ c. Because no transpose is needed and it is not a script
+ flat1d should work faster than colflat.
+ d. The prompts for interactive fitting are now correct when
+ doing column fits.
+
+------
+From Valdes on July 23, 1985:
+
+1. The task revisions has been added to page revisions to the generic
+package. The intent is that each package will have a revisions task.
+Note that this means there may be multiple tasks named revisions loaded
+at one time. Typing revisions alone will give the revisions for the
+current package. To get the system revisions type system.revisions.
+
+2. The tasks linebckgrnd and colbckgrnd have been combined into one
+task with the extra hidden parameter "axis". With axis=1 the task
+is the same as linebckgrnd and with axis=2 the task is the same as
+colbckgrnd.
+.endhelp
diff --git a/noao/imred/generic/background.cl b/noao/imred/generic/background.cl
new file mode 100644
index 00000000..005703ed
--- /dev/null
+++ b/noao/imred/generic/background.cl
@@ -0,0 +1,6 @@
+#{ BACKGROUND -- Subtract a line or column background.
+
+fit1d (input, output, "difference", axis=axis, interactive=interactive,
+ sample=sample, naverage=naverage, function=function, order=order,
+ low_reject=low_reject, high_reject=high_reject, niterate=niterate,
+ grow=grow, graphics=graphics, cursor=cursor.p_filename)
diff --git a/noao/imred/generic/background.par b/noao/imred/generic/background.par
new file mode 100644
index 00000000..aa5c703a
--- /dev/null
+++ b/noao/imred/generic/background.par
@@ -0,0 +1,16 @@
+# BACKGROUND -- Subtract line or column background
+
+input,s,a,,,,Input images to be background subtracted
+output,s,a,,,,Output background subtracted images
+axis,i,h,1,1,2,Axis along which background is fit and subtracted
+interactive,b,h,yes,,,Set fitting parameters interactively?
+sample,s,h,"*",,,Sample of points to use in fit
+naverage,i,h,1,,,Number of points in sample averaging
+function,s,h,"chebyshev","spline3|legendre|chebyshev|spline1",,Fitting function
+order,i,h,1,1,,Order of fitting function
+low_reject,r,h,0.,0.,,Low rejection in sigma of fit
+high_reject,r,h,0.,0.,,High rejection in sigma of fit
+niterate,i,h,1,0,,Number of rejection iterations
+grow,r,h,0.,0.,,Rejection growing radius
+graphics,s,h,"stdgraph",,,Graphics output device
+cursor,*gcur,h,"",,,Graphics cursor input
diff --git a/noao/imred/generic/darksub.cl b/noao/imred/generic/darksub.cl
new file mode 100644
index 00000000..c4197c50
--- /dev/null
+++ b/noao/imred/generic/darksub.cl
@@ -0,0 +1,99 @@
+# DARKSUB -- Scale and subtract a dark count image.
+
+procedure darksub (input, output, darkimage)
+
+string input {prompt="Input images to be dark count subtracted"}
+string output {prompt="Output dark count subtracted images"}
+file darkimage {prompt="Dark count image"}
+
+string exposure {prompt="Header parameter for exposure times"}
+string pixtype="1" {prompt="Pixel type of final images"}
+bool verbose=yes {prompt="Verbose output?"}
+struct *list1
+struct *list2
+
+begin
+ file darkim
+ file dark
+ file file1
+ file file2
+ string in
+ string out
+ real exp
+ real expd
+ real expi
+ int stat
+
+ # Make temporary filenames.
+ dark = mktemp ("tmp")
+ file1 = mktemp ("tmp")
+ file2 = mktemp ("tmp")
+
+ # Determine exposure time of dark image. Quit if no exposure time.
+ darkim = darkimage
+ hselect (darkim, exposure, yes, > file1)
+ list1 = file1
+ stat = fscan (list1, expd)
+ list1 = ""
+ delete (file1, verify=no)
+
+ if (stat == EOF || nscan() < 1)
+ error (1, "Exposure time for " // darkim // " not found.")
+ if (expd == 0.)
+ error (2, "Exposure time for " // darkim // " is zero.")
+ exp = expd
+
+ # Make a temporary image for the scaled dark.
+ imcopy (darkim, dark, verbose=no)
+
+ # Expand the list of input and output images in temporary files.
+ hselect (input, "$I,"//exposure, yes, > file1)
+ sections (output, option="root", > file2)
+
+ # Loop through the input and output images.
+ list1 = file1
+ list2 = file2
+ while (fscan (list1, in, expi) != EOF) {
+
+ stat = nscan()
+
+ # Check that the output list has not been exhausted.
+ if (fscan (list2, out) == EOF) {
+ print (" Output list exhausted before input list.")
+ break
+ }
+
+ # Check that there is an exposure time for the input image.
+ if (stat < 2) {
+ print (" Exposure time for ", in, " not found.")
+ next
+ }
+ if (expi == 0.) {
+ print (" Exposure time for ", in, " is zero.")
+ next
+ }
+
+ # Print log output.
+ if (verbose) {
+ time ()
+ print (" ", out, " = ", in, " - ", expi/expd, "* ", darkim)
+ }
+
+ # Scale the dark image if necessary.
+ if (expi != exp) {
+ imarith (dark, "*", expi / exp, dark, title="", divzero=0.,
+ hparams="", pixtype="", calctype="", verbose=no, noact=no)
+ exp = expi
+ }
+
+ # Subtract the dark image from the input image.
+ imarith (in, "-", dark, out, title="", divzero=0.,
+ hparams="", pixtype=pixtype, calctype=pixtype,
+ verbose=no, noact=no)
+ }
+
+ # Finish up.
+ imdelete (dark, verify=no)
+ delete (file1, verify=no)
+ delete (file2, verify=no)
+end
diff --git a/noao/imred/generic/doc/Spelldict b/noao/imred/generic/doc/Spelldict
new file mode 100644
index 00000000..bb9573fb
--- /dev/null
+++ b/noao/imred/generic/doc/Spelldict
@@ -0,0 +1,51 @@
+Chebyshev
+INDEF
+IRAF
+Oct84
+RMS
+Sep84
+biasimage
+biassub
+ccd
+chebyshev
+chimage.section
+chimages
+chimages.section
+chimages.transpose
+colbckgrnd
+colflat
+darkimage
+darksub
+datatype
+dcbias
+dcbias.bias
+dcbias.trim
+div
+elp
+expdark
+expimage
+flatfield
+fliplines
+frame1
+frame2
+frame3
+images.imcopy
+imarith
+imcopy
+imlinefit
+imred.keeplog
+imred.logfile
+imstatistics
+imtranspose
+legendre
+linebckgrnd
+lineflat
+min
+minflat
+ndhelp
+ngrow
+normflat
+pixtype
+spline3
+trim.section
+
diff --git a/noao/imred/generic/doc/background.hlp b/noao/imred/generic/doc/background.hlp
new file mode 100644
index 00000000..7fa1fdd6
--- /dev/null
+++ b/noao/imred/generic/doc/background.hlp
@@ -0,0 +1,82 @@
+.help background Jul85 noao.imred.generic
+.ih
+NAME
+background -- Fit and subtract a line or column background
+.ih
+USAGE
+background input output
+.ih
+PARAMETERS
+.ls input
+Images to be background subtracted. The images may contain image sections.
+.le
+.ls output
+Output images to be created and modified. The number of output images must
+match the number of input images.
+.le
+.ls axis = 1
+Axis along which to fit the background and subtract. Axis 1 fits and
+subtracts the background along the lines and axis 2 fits and subtracts
+the background along the columns.
+.le
+.ls interactive = yes
+Set the fitting parameters interactively?
+.le
+.ls sample = "*"
+Lines or columns to be used in the background fits. The default "*" selects
+all lines or columns.
+.le
+.ls naverage = 1
+Number of sample points to combined to create a fitting point.
+A positive value specifies an average and a negative value specifies
+a median.
+.le
+.ls function = spline3
+Function to be fit to the image lines or columns. The functions are
+"legendre" (legendre polynomial), "chebyshev" (chebyshev polynomial),
+"spline1" (linear spline), and "spline3" (cubic spline). The functions
+may be abbreviated.
+.le
+.ls order = 1
+The order of the polynomials or the number of spline pieces.
+.le
+.ls low_reject = 0., high_reject = 0.
+Low and high rejection limits in units of the residual sigma.
+.le
+.ls niterate = 1
+Number of rejection iterations.
+.le
+.ls grow = 1.
+When a pixel is rejected, pixels within this distance of the rejected pixel
+are also rejected.
+.le
+.ls graphics = "stdgraph"
+Graphics device for interactive graphics output.
+.le
+.ls cursor = ""
+Graphics cursor input
+.le
+.ih
+DESCRIPTION
+For each line or column in the input images a function is fit to the columns
+or lines specified by the sample parameter. This function is then subtracted
+from the entire line or column to create an output line or column.
+The function fitting parameters may be set interactively.
+This task is a script using \fBfit1d\fR. For more discussion about
+the parameters see the help text for \fBicfit\fR and \fBfit1d\fR.
+.ih
+EXAMPLES
+A spectrum of an object runs down the center of a 500 x 500 image. To
+subtract a constant background using columns 10 to 100 and 410 to 500:
+
+ cl> background image image sample="10:100,410:500"
+
+To subtract a quadratic background from the columns of an image in which
+the spectrum lies between lines 50 and 70:
+
+ cl> background image image axis=2 sample="1:40,80:120" o=3
+
+.ih
+SEE ALSO
+fit1d, icfit
+.endhelp
diff --git a/noao/imred/generic/doc/darksub.hlp b/noao/imred/generic/doc/darksub.hlp
new file mode 100644
index 00000000..c6349e03
--- /dev/null
+++ b/noao/imred/generic/doc/darksub.hlp
@@ -0,0 +1,60 @@
+.help darksub Apr86 noao.imred.generic
+.ih
+NAME
+darksub -- Scale and subtract a dark count image
+.ih
+USAGE
+darksub input output darkimage
+.ih
+PARAMETERS
+.ls input
+List of input images from which to subtract the dark count image.
+.le
+.ls output
+List of output dark count subtracted images. The output images may
+be the same as the input images. The input and output image lists should
+contain the same number of images.
+.le
+.ls darkimage
+Dark count image to be scaled and subtracted from the input images.
+.le
+.ls exposure = ""
+Header parameter name from which to obtain the exposure times.
+.le
+.ls pixtype = "1"
+The pixel datatype of the dark subtracted images. The default ("1")
+is the pixel datatype of the original image. The other choices are
+"short", "integer", "long", "real", and "double".
+.le
+.ls verbose = yes
+Print log of operations performed.
+.le
+.ih
+DESCRIPTION
+The dark count image is scaled by the ratio of the input image exposure to the
+dark count image exposure and subtracted from each of the input images.
+The exposures are obtained from the image headers under the specified
+name. The output images may have the same names as the input images.
+A temporary image is used for the scaled dark count image and the original
+image is not modified. The pixel datatype of the output images is
+specified by the parameter \fIpixtype\fR. The default ("1") uses the
+datatype of the input image. A log of the operations performed may be
+printed on the standard output when the verbose options is specified.
+
+Note that this task can be used to subtract any type of image from a set
+of images in which the subtracted image must be scaled to a given exposure.
+.ih
+EXAMPLES
+To subtract the dark count image 'dark' from obs1, obs2, and obs3:
+
+.nf
+ cl> darksub obs1,obs2 obs1,obs2 dark exp="exposure"
+ Tue 18:50:56 08-Apr-86
+ obs1 = obs1 - 5.0049997336067 * dark
+ Tue 18:51:05 08-Apr-86
+ obs2 = obs2 - 5.009999733075 * dark
+.fi
+.ih
+SEE ALSO
+imarith
+.endhelp
diff --git a/noao/imred/generic/doc/flat1d.hlp b/noao/imred/generic/doc/flat1d.hlp
new file mode 100644
index 00000000..0f855828
--- /dev/null
+++ b/noao/imred/generic/doc/flat1d.hlp
@@ -0,0 +1,157 @@
+.help flat1d Mar93 noao.imred.generic
+.ih
+NAME
+flat1d -- Make flat fields by fitting a 1D function to the image
+.ih
+USAGE
+flat1d input output
+.ih
+PARAMETERS
+.ls input
+Calibration images to be used to make the flat fields. The images may
+contain image sections. Only the region covered by the section will be
+modified in the output image.
+.le
+.ls output
+Flat field images to be created or modified. The number of output images
+must match the number of input images. If an output image does not exist
+it is first created and initialized to unit response.
+.le
+.ls axis = 1
+Axis along which the one dimensional fitting is done. Axis 1 corresponds
+to fitting the image lines and axis 2 corresponds to fitting the columns.
+.le
+.ls interactive = yes
+Set the fitting parameters interactively?
+.le
+.ls sample = "*"
+Lines or columns to be used in the fits.
+.le
+.ls naverage = 1
+Number of sample points to combined to create a fitting point.
+A positive value specifies an average and a negative value specifies
+a median.
+.le
+.ls function = spline3
+Function to be fit to the image lines or columns. The functions are
+"legendre" (legendre polynomial), "chebyshev" (chebyshev polynomial),
+"spline1" (linear spline), and "spline3" (cubic spline). The functions
+may be abbreviated.
+.le
+.ls order = 1
+The order of the polynomials or the number of spline pieces.
+.le
+.ls low_reject = 2.5, high_reject = 2.5
+Low and high rejection limits in units of the residual sigma.
+.le
+.ls niterate = 1
+Number of rejection iterations.
+.le
+.ls grow = 1.
+When a pixel is rejected, pixels within this distance of the rejected pixel
+are also rejected.
+.le
+.ls minflat = 0.
+When the fitted value is less than the value of this parameter the flat
+field value is set to unity.
+.le
+.ls graphics = "stdgraph"
+Graphics device for interactive graphics output.
+.le
+.ls cursor = ""
+Graphics cursor input
+.le
+.ih
+DESCRIPTION
+Flat fields are created containing only the small scale variations in the
+calibration images. The large scale variations in the images are modeled
+by fitting a function to each image line or column with deviant pixel rejection.
+The flat field values are obtained by taking the ratio of the image values
+to the function fit. However, if the fitted value is less than the
+parameter \fIminflat\fR the flat field value is set to unity.
+
+The function fitting parameters may be set interactively when the interactive
+flag is set using the interactive curve fitting package \fBicfit\fR.
+The cursor mode commands for this package are described in a separate
+help entry under "icfit". For two dimensional images the user is
+prompted for the sample line or column or a blank-separated range to be
+averaged and graphed.
+Note that the lines or columns are relative the input image section; for
+example line 1 is the first line of the image section and not the first
+line of the image. Any number of lines or columns may be examined.
+When satisfied with the fit parameters the user
+responds with a carriage return to the line or column prompt.
+The function is then fit to all the lines or columns and the flat field
+ratios are determined.
+
+If the output image does not exist initially it is created with the same
+size as the input image \fIwithout\fR an image section and initialized
+to unit response. Subsequently the flat field data modifies the pixel
+values in the output image. Input image sections may be used to restrict
+the region in which the flat field response is determined leaving the
+rest of the output image unmodified. This ability is particularly useful
+when dealing with multi-aperture data.
+
+This task is very similar to \fBfit1d\fR with the addition of the
+parameter \fIminflat\fR and the deletion of the parameter \fItype\fR
+which is always "ratio".
+.ih
+EXAMPLES
+1. Create a flat field from the calibration image "quartz" with the
+spectrum running along the lines. Exclude the first and last columns,
+use a spline fit of 25 pieces (a width of 32 pixels over 800 columns),
+and set grow to 4 pixels.
+
+.nf
+ cl> flat1d quartz flat order=25 sample="2:799" grow=4 \
+ >>> interactive=no
+
+ or
+
+ cl> flat1d quartz[2:799,*] flat order=25 grow=4 inter-
+.fi
+
+The fitting parameters may be set interactively in which case the fitting
+parameters need not be specified. The command would be
+
+.nf
+ cl> flat1d quartz flat
+ quartz: Fit column = 1 10
+ quartz: Fit column =
+.fi
+
+The user selects sample columns to be fit interactively with the interactive
+curve fitting package. When satisfied with the fit parameters
+respond with a carriage return to the prompt. The function is then fit to
+all the columns and the flat field ratios are determined.
+
+2. As an example for multi-slit spectra the locations of the slits are
+determined and a file containing the image sections is created.
+Since there must be the same number of output images another file
+containing the output images is also created. For
+example the files might contain
+
+.nf
+ File quartzs File flats
+ _______________ __________
+ quartz[23:40,*] flat
+ quartz[55:61,*] flat
+ quartz[73:84,*] flat
+.fi
+
+A flat field for the slits is then obtained with the command
+
+ cl> flat1d @quartzs flats axis=2
+.ih
+REVISIONS
+.ls FLAT1D V2.10.3
+The image header keyword "CCDMEAN = 1." is now added or updated.
+.le
+.ih
+BUGS
+The creation of multi-slit files and the need for an equal number of
+repeated output files is annoying. It will be worked on in the future.
+.ih
+SEE ALSO
+fit1d, icfit
+.endhelp
diff --git a/noao/imred/generic/doc/flatten.hlp b/noao/imred/generic/doc/flatten.hlp
new file mode 100644
index 00000000..0e35f647
--- /dev/null
+++ b/noao/imred/generic/doc/flatten.hlp
@@ -0,0 +1,42 @@
+.help flatten Sep84 noao.imred.generic
+.ih
+NAME
+flatten -- Flatten images by dividing by a flat field
+.ih
+USAGE
+flatten images flatfield
+.ih
+PARAMETERS
+.ls images
+Images to be flattened.
+.le
+.ls flatfield
+Flat field image to be divided into the images.
+.le
+.ls minflat = INDEF
+All flat field pixels less than or equal to this value are replaced by
+unit response. If INDEF all the flat field pixels are used.
+.le
+.ls pixtype = "real"
+The pixel datatype of the flattened image. The null string ("") defaults
+the pixel datatype to that of the original image before flattening.
+The other choices are "short", "integer", "long", and "real".
+.le
+.ih
+DESCRIPTION
+Each of the \fIimages\fR is flatten by dividing by the \fIflatfield\fR
+flat field image. The flattened images replace the original images.
+The pixel datatype of the flattened images is specified by the
+\fIpixtype\fR. The null string ("") leaves the datatype of the images
+unchanged. Low values in the flat field may be replaced by unit response
+by specifying a \fIminflat\fR value. All pixels in the flat field less
+than or equal to \fIminflat\fR are given unit response.
+.ih
+EXAMPLES
+To flatten a set of two dimensional images excluding pixels below
+.2 in the flat field:
+
+.nf
+ cl> flatten frame* flat minflat=0.2
+.fi
+.endhelp
diff --git a/noao/imred/generic/doc/normalize.hlp b/noao/imred/generic/doc/normalize.hlp
new file mode 100644
index 00000000..f5fb80f7
--- /dev/null
+++ b/noao/imred/generic/doc/normalize.hlp
@@ -0,0 +1,45 @@
+.help normalize Sep84 noao.imred.generic
+.ih
+NAME
+normalize -- Normalize images
+.ih
+USAGE
+normalize images
+.ih
+PARAMETERS
+.ls images
+Images to be normalized.
+.le
+.ls norm = INDEF
+Normalization factor to be used if not INDEF. If INDEF the normalization
+factor is determined by sampling the images.
+.le
+.ls sample_section = "[]"
+Section of the image to be sampled in determining the image mean.
+.le
+.ls lower = INDEF
+Lower limit of pixel values for calculating the normalization.
+INDEF corresponds to the minimum possible pixel value.
+.le
+.ls upper = INDEF
+Upper limit of pixel values for calculating the normalization.
+INDEF corresponds to the maximum possible pixel value.
+.le
+.ih
+DESCRIPTION
+Each of the images is normalized. The normalization is specified by the
+parameter \fInorm\fR. If the value of \fInorm\fR is INDEF then a normalization
+is determined by sampling the image. The normalization is then the mean
+of the pixels in the sample section with values in the range \fIlower\fR
+to \fIupper\fR. The default sample section selects all pixels in the image.
+The normalized images are of datatype "real" and replace the original images.
+.ih
+EXAMPLES
+To normalize a set of two dimensional images excluding deviant pixels below
+1000 and above 5000 and subsampling every fifth pixel in each dimension:
+
+ cl> normalize frame* sample=[*:5,*:5] low=1000 up=5000
+.ih
+SEE ALSO
+imstatistics, normflat
+.endhelp
diff --git a/noao/imred/generic/doc/normflat.hlp b/noao/imred/generic/doc/normflat.hlp
new file mode 100644
index 00000000..3020d296
--- /dev/null
+++ b/noao/imred/generic/doc/normflat.hlp
@@ -0,0 +1,54 @@
+.help normflat Sep84 noao.imred.generic
+.ih
+NAME
+normflat -- Create a flat field by normalizing a calibration image
+.ih
+USAGE
+normflat image flatfield
+.ih
+PARAMETERS
+.ls image
+Calibration image to be used.
+.le
+.ls flatfield
+Flat field to be created.
+.le
+.ls norm = INDEF
+Normalization factor to be used if not INDEF. If INDEF the normalization
+factor is automatically determined.
+.le
+.ls minflat = INDEF
+Minimum data value to be used in determining the normalization and in
+creating the flat field. Values less than or equal to this value are
+replaced with a flat field value of 1.
+.le
+.ls sample_section = "[]"
+Section of the image to be sampled in determining the normalization if
+norm = INDEF.
+.le
+.ih
+DESCRIPTION
+A flat field is created from a calibration image by normalizing the calibration
+image. The normalization is specified with the parameter \fInorm\fR. If the
+value of \fInorm\fR is INDEF then the normalization is determined by sampling
+the pixels in the sample section with values greater than \fIminflat\fR.
+This task differs from the task \fBnormalize\fR in that data values less
+than or equal to \fIminflat\fR are replaced with unity in the normalized
+flat field.
+.ih
+EXAMPLES
+To create a flat field from a calibration image "quartz" using pixels
+above 1000 and selecting the normalization to be 3500:
+
+ cl> normflat quartz flat norm=3500 minflat=1000
+
+To determine a normalization from the pixels above 1000 and sampling
+every fifth pixel in each dimension:
+
+.nf
+ cl> normflat quartz flat minflat=1000 sample=[*:5,*:5]
+.fi
+.ih
+SEE ALSO
+normalize
+.endhelp
diff --git a/noao/imred/generic/flat1d.par b/noao/imred/generic/flat1d.par
new file mode 100644
index 00000000..90e0ad3d
--- /dev/null
+++ b/noao/imred/generic/flat1d.par
@@ -0,0 +1,17 @@
+# FLAT1D -- Make flat fields by fitting a function to the image line or cols.
+
+input,s,a,,,,Calibration images
+output,s,a,,,,Flat field images
+axis,i,h,1,1,2,Axis to fit
+interactive,b,h,yes,,,Set fitting parameters interactively?
+sample,s,h,"*",,,Sample points to use in fit
+naverage,i,h,1,,,Number of points in sample averaging
+function,s,h,"spline3","spline3|legendre|chebyshev|spline1",,Fitting function
+order,i,h,1,1,,Order of fitting function
+low_reject,r,h,2.5,0.,,Low rejection in sigma of fit
+high_reject,r,h,2.5,0.,,High rejection in sigma of fit
+niterate,i,h,1,0,,Number of rejection iterations
+grow,r,h,1.,0.,,Rejection growing radius in pixels
+minflat,r,h,0.,,,Minimum fit value for computing a flat field value
+graphics,s,h,"stdgraph",,,Graphics output device
+cursor,*gcur,h,"",,,Graphics cursor input
diff --git a/noao/imred/generic/flat1d.x b/noao/imred/generic/flat1d.x
new file mode 100644
index 00000000..5a0797fc
--- /dev/null
+++ b/noao/imred/generic/flat1d.x
@@ -0,0 +1,478 @@
+include <error.h>
+include <imhdr.h>
+include <pkg/gtools.h>
+
+# FLAT1D -- Fit a function to image lines or columns and output an image
+# consisting of the ratio. Set a minimum value test to the denominator.
+# The fitting parameters may be set interactively using the icfit package.
+
+procedure flat1d ()
+
+int listin # Input image list
+int listout # Output image list
+int axis # Image axis to fit
+real minflat # Minimum fit value for ratio
+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
+
+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
+
+int imtopen(), imtgetim(), imtlen(), gt_init()
+int clgeti()
+real clgetr()
+bool clgetb()
+
+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")
+ minflat = clgetr ("minflat")
+ interactive = clgetb ("interactive")
+
+ # Initialize the ICFIT package.
+ 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")
+
+ 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 each input image.
+
+ while ((imtgetim (listin, input, SZ_LINE) != EOF) &&
+ (imtgetim (listout, output, SZ_FNAME) != EOF)) {
+
+ iferr (call f1d_immap (input, output, in, out)) {
+ call erract (EA_WARN)
+ next
+ }
+ call f1d_flat1d (in, out, ic, gt, input, axis, minflat, interactive)
+ call imunmap (in)
+ call imunmap (out)
+ }
+
+ call ic_closer (ic)
+ call gt_free (gt)
+ call imtclose (listin)
+ call imtclose (listout)
+end
+
+
+# F1D_FLAT1D -- 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.
+
+define MAXBUF 512 * 100 # Maximum number of pixels per block
+
+procedure f1d_flat1d (in, out, ic, gt, title, axis, minflat, 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
+real minflat # Minimum value for flat division
+bool interactive # Interactive?
+
+char graphics[SZ_FNAME]
+int i, nx, new
+real mindata, maxdata
+pointer cv, gp, sp, x, wts, indata, outdata
+
+int f1d_getline(), f1d_getdata(), strlen()
+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 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 alimr (Memr[indata], nx, mindata, maxdata)
+ if (maxdata >= minflat) {
+ call ic_fit (ic, cv, Memr[x], Memr[indata], Memr[wts],
+ nx, new, YES, new, new)
+ new = NO
+
+ call cvvector (cv, Memr[x], Memr[outdata], nx)
+ }
+
+ call f1d_flat (Memr[indata], Memr[outdata], Memr[outdata], nx,
+ minflat, mindata, maxdata)
+ }
+
+ call imaddr (out, "ccdmean", 1.)
+
+ call cvfree (cv)
+ call sfree (sp)
+end
+
+
+# F1D_IMMAP -- Map images for flat1d.
+
+procedure f1d_immap (input, output, in, out)
+
+char input[ARB] # Input image
+char output[ARB] # Output image
+pointer in # Input IMIO pointer
+pointer out # Output IMIO pointer
+
+pointer sp, root, sect, line, data
+
+int access(), impnlr()
+pointer immap()
+errchk immap
+
+begin
+ # Get the root name and section of the input image.
+
+ call smark (sp)
+ call salloc (root, SZ_FNAME, TY_CHAR)
+ call salloc (sect, SZ_FNAME, TY_CHAR)
+
+ call get_root (input, Memc[root], SZ_FNAME)
+ call get_section (input, Memc[sect], SZ_FNAME)
+
+ # If the output image is not accessible then create it as a new copy
+ # of the full input image and initialize to unit response.
+
+ if (access (output, READ_WRITE, BINARY_FILE) == NO) {
+ in = immap (Memc[root], READ_ONLY, 0)
+ out = immap (output, NEW_COPY, in)
+ IM_PIXTYPE(out) = TY_REAL
+
+ call salloc (line, IM_MAXDIM, TY_LONG)
+ call amovkl (long (1), Meml[line], IM_MAXDIM)
+ 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.
+
+ in = immap (input, READ_ONLY, 0)
+
+ call sprintf (Memc[root], SZ_FNAME, "%s%s")
+ call pargstr (output)
+ call pargstr (Memc[sect])
+ out = immap (Memc[root], READ_WRITE, 0)
+
+ 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_FLAT -- For the flat field values by ratioing the image data by the fit.
+# If the fit value is less than minflat then the ratio is set to 1.
+
+procedure f1d_flat (data, fit, flat, npts, minflat, mindata, maxdata)
+
+real data[npts] # Image data
+real fit[npts] # Fit to image data
+real flat[npts] # Ratio of image data to the fit
+int npts # Number of points
+real minflat # Minimum fit value for ratio
+real mindata # Minimum data value
+real maxdata # Maximum data value
+
+int i
+
+begin
+ if (mindata >= minflat)
+ call adivr (data, fit, flat, npts)
+
+ else if (maxdata < minflat)
+ call amovkr (1., flat, npts)
+
+ else {
+ do i = 1, npts {
+ if (fit[i] < minflat)
+ flat[i] = 1.
+ else
+ flat[i] = data[i] / fit[i]
+ }
+ }
+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
+
+char line[SZ_LINE]
+int i, j, stat, imlen
+pointer x
+
+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
diff --git a/noao/imred/generic/flatten.cl b/noao/imred/generic/flatten.cl
new file mode 100644
index 00000000..928e09b2
--- /dev/null
+++ b/noao/imred/generic/flatten.cl
@@ -0,0 +1,64 @@
+#{ FLATTEN -- Divide images by a flat field
+
+#images,s,a,,,,Images to be flattened
+#flatfield,f,a,,,,Flat field
+#minflat,r,h,INDEF,,,Minimum flat field value
+#pixtype,s,h,"real",,,Flattened image pixel datatype
+#keeplog,b,h,@generic.keeplog,,,Keep log of processing?
+#logfile,f,h,@generic.logfile,,,Log file
+#imlist,f,h
+#imfd,*s,h
+#input,f,h
+#flat,f,h
+#flt,f,h
+
+{
+ # Startup message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" FLATTEN: Flatten images.", >> logfile)
+ }
+
+ # Set temporary files.
+ imlist = mktemp ("tmp$ims")
+
+ # Replace low flat field values if needed.
+ flat = flatfield
+ if (minflat == INDEF)
+ flt = flat
+ else {
+ if (keeplog)
+ print (" Minimum flat field value = ", minflat, >> logfile)
+ flt = mktemp ("tmp$ims")
+ imcopy (flat, flt, verbose=no)
+ imreplace (flt, 1., upper=minflat)
+ }
+
+ # Generate image list.
+ sections (images, option="fullname", >imlist)
+ imfd = imlist
+
+ while (fscan (imfd, input) != EOF) {
+
+ # Print output.
+ if (keeplog) {
+ time (>> logfile)
+ print (" Flatten ", input, " with ", flat, ".", >> logfile)
+ }
+
+ # Flatten the image with the flat field. Replace the input
+ # image by the flattened image.
+
+ imarith (input, "/", flt, input, pixtype=pixtype, calctype="real")
+ }
+
+ if (minflat != INDEF)
+ imdelete (flt, verify=no)
+ delete (imlist, verify=no)
+
+ # Ending message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" FLATTEN: Done.", >> logfile)
+ }
+}
diff --git a/noao/imred/generic/flatten.par b/noao/imred/generic/flatten.par
new file mode 100644
index 00000000..7eedfe58
--- /dev/null
+++ b/noao/imred/generic/flatten.par
@@ -0,0 +1,13 @@
+# FLATTEN -- Divide images by a flat field
+
+images,s,a,,,,Images to be flattened
+flatfield,f,a,,,,Flat field
+minflat,r,h,INDEF,,,Minimum flat field value
+pixtype,s,h,"real",,,Flattened image pixel datatype
+keeplog,b,h,)generic.keeplog,,,Keep log of processing?
+logfile,f,h,)generic.logfile,,,Log file
+imlist,f,h
+imfd,*s,h
+input,f,h
+flat,f,h
+flt,f,h
diff --git a/noao/imred/generic/generic.cl b/noao/imred/generic/generic.cl
new file mode 100644
index 00000000..8a187758
--- /dev/null
+++ b/noao/imred/generic/generic.cl
@@ -0,0 +1,17 @@
+#{ GENERIC -- Generic image reduction tools
+
+# Load dependent packages:
+images
+proto # Task "imreplace"
+
+package generic
+
+task flat1d = generic$x_generic.e
+
+task background = generic$background.cl
+task darksub = generic$darksub.cl
+task flatten = generic$flatten.cl
+task normalize = generic$normalize.cl
+task normflat = generic$normflat.cl
+
+clbye()
diff --git a/noao/imred/generic/generic.hd b/noao/imred/generic/generic.hd
new file mode 100644
index 00000000..3464ed28
--- /dev/null
+++ b/noao/imred/generic/generic.hd
@@ -0,0 +1,11 @@
+# Help directory for the GENERIC package.
+
+$doc = "./doc/"
+
+background hlp=doc$background.hlp, src=background.cl
+darksub hlp=doc$darksub.hlp, src=darksub.cl
+flatten hlp=doc$flatten.hlp, src=flatten.cl
+flat1d hlp=doc$flat1d.hlp, src=flat1d.x
+normalize hlp=doc$normalize.hlp, src=normalize.cl
+normflat hlp=doc$normflat.hlp, src=normflat.cl
+revisions sys=Revisions
diff --git a/noao/imred/generic/generic.men b/noao/imred/generic/generic.men
new file mode 100644
index 00000000..9241c0d7
--- /dev/null
+++ b/noao/imred/generic/generic.men
@@ -0,0 +1,6 @@
+ background - Fit and subtract a line or column background
+ darksub - Scale and subtract a dark count image
+ flat1d - Make flat field by fitting a 1D func. to the lines or columns
+ flatten - Flatten images using a flat field
+ normalize - Normalize images
+ normflat - Create a flat field by normalizing and replacing low values
diff --git a/noao/imred/generic/generic.par b/noao/imred/generic/generic.par
new file mode 100644
index 00000000..7c5c6b6c
--- /dev/null
+++ b/noao/imred/generic/generic.par
@@ -0,0 +1,5 @@
+# GENERIC package parameter file.
+
+keeplog,b,h,)imred.keeplog,,,Keep log of processing?
+logfile,f,h,)imred.logfile,,,Log file
+version,s,h,"May 1985"
diff --git a/noao/imred/generic/mkpkg b/noao/imred/generic/mkpkg
new file mode 100644
index 00000000..2c33031b
--- /dev/null
+++ b/noao/imred/generic/mkpkg
@@ -0,0 +1,54 @@
+# Make the GENERIC package.
+# Make the GENERIC package.
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $update libpkg.a
+ $call generic
+ ;
+
+install:
+ $move x_generic.e noaobin$
+ ;
+
+generic:
+ $omake x_generic.x
+ $link x_generic.o libpkg.a -lxtools -lcurfit
+ ;
+
+libpkg.a:
+ flat1d.x <imhdr.h> <pkg/gtools.h>
+ ;
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $update libpkg.a
+ $call generic
+ ;
+
+install:
+ $move x_generic.e noaobin$
+ ;
+
+generic:
+ $omake x_generic.x
+ $link x_generic.o libpkg.a -lxtools -lcurfit
+ ;
+
+libpkg.a:
+ flat1d.x <imhdr.h> <pkg/gtools.h> <error.h>
+ ;
diff --git a/noao/imred/generic/normalize.cl b/noao/imred/generic/normalize.cl
new file mode 100644
index 00000000..59290c1c
--- /dev/null
+++ b/noao/imred/generic/normalize.cl
@@ -0,0 +1,79 @@
+# NORMALIZE -- Compute the average of a sample region and normalize.
+
+procedure normalize (images)
+
+string images {prompt="Images to be normalized"}
+real norm = INDEF {prompt="Normalization value"}
+string sample_section = "[]" {prompt="Sample section"}
+real lower = INDEF {prompt="Lower limit of data values for sampling"}
+real upper = INDEF {prompt="Upper limit of data values for sampling"}
+bool keeplog = ")_.keeplog" {prompt="Keep log of processing?"}
+file logfile = ")_.logfile" {prompt="Log file"}
+
+struct *imfd
+
+begin
+ file imlist, input, tmp
+ real mean
+ int stat
+ bool mef
+
+ mef = no
+
+ # Query parameters.
+ input = images
+
+ # Set temporary files.
+ imlist = mktemp ("tmp$ims")
+ tmp = mktemp ("tmp")
+
+ # Startup message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" NORMALIZE: Normalize images.", >> logfile)
+ }
+
+ # Generate image list.
+ sections (input, option="fullname", >imlist)
+
+ # Process list.
+ imfd = imlist
+ while (fscan (imfd, input) != EOF) {
+
+ # Determine normalization.
+ if (norm == INDEF) {
+ # Determine the mean of the sample region.
+ imstatistics (input // sample_section, fields="mean",
+ lower=lower, upper=upper, format=no) | scan (mean)
+ } else
+ mean = norm
+
+ # Print output.
+ if (keeplog) {
+ time (>> logfile)
+ print (" Normalization for ", input, " = ", mean, >> logfile)
+ }
+
+ if (mean != 0.) {
+ # Normalize the image by the mean.
+ if (mef) {
+ imarith (input, "/", mean, tmp, pixtype="real",
+ calctype="real")
+ imcopy (tmp, input//"[]", verbose-)
+ imdelete (tmp, verify-)
+ } else
+ imarith (input, "/", mean, input, pixtype="real",
+ calctype="real")
+ hedit (input, "ccdmean", 1., add=yes, verify=no, show=no,
+ update=yes)
+ } else
+ print (" WARNING: Cannot normalize ", input, ".")
+ }
+ imfd = ""; delete (imlist, verify=no)
+
+ # Ending message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" NORMALIZE: Done.", >> logfile)
+ }
+end
diff --git a/noao/imred/generic/normflat.cl b/noao/imred/generic/normflat.cl
new file mode 100644
index 00000000..60b7025b
--- /dev/null
+++ b/noao/imred/generic/normflat.cl
@@ -0,0 +1,69 @@
+#{ NORMFLAT -- Make a flat field by normalizing and replacing low values.
+
+# image,f,a,,,,Calibration image
+# flatfield,f,a,,,,Flat field image
+# norm,r,h,INDEF,,,Normalization if not INDEF
+# minflat,r,h,INDEF,,,Minimum data value to use in the flat field
+# sample_section,s,h,"[]",,,Sample section for determining normalization
+# keeplog,b,h,@generic.keeplog,,,Keep log of processing?
+# logfile,f,h,@generic.logfile,,,Log file
+# img,f,h
+# flt,f,h
+# tmp,f,h
+# rlist,*s,h
+# mean,r,h
+# stat,i,h
+
+{
+ # Get query parameters and set temporary parameters.
+ img = image
+ flt = flatfield
+ tmp = mktemp ("tmp$gec")
+
+ # Startup message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" NORMFLAT: Create a flat field.\n", >> logfile)
+ print (" Calibration image: ", img, >> logfile)
+ print (" Flat field: ", flt, >> logfile)
+ if (minflat != INDEF)
+ print (" Minimum data value used in flat field = ", minflat,
+ >> logfile)
+ }
+
+ # Determine normalization.
+ if (norm == INDEF) {
+ # Determine the mean of the sample region.
+
+ imstatistics (img // sample_section, fields="mean",
+ lower=minflat, upper=INDEF, format=no, > tmp)
+ rlist = tmp
+ stat = fscan (rlist, mean)
+ rlist = ""
+ delete (tmp, verify=no)
+ } else
+ mean = norm
+
+ if (keeplog)
+ print (" Normalization = ", mean, >> logfile)
+
+ # Replace low values by the mean and normalize.
+ if (mean != 0.) {
+ if (minflat != INDEF) {
+ imcopy (img, flt, verbose=no)
+ imreplace (flt, mean, upper=minflat)
+ imarith (flt, "/", mean, flt, pixtype="real")
+ } else
+ imarith (img, "/", mean, flt, pixtype="real")
+ } else
+ print (" ERROR: Cannot normalize calibration image.")
+
+ # Set CCDMEAN to 1.
+ hedit (flt, "ccdmean", "1.", add=yes, update=yes, show=no, verify=no)
+
+ # Ending message.
+ if (keeplog) {
+ time (>> logfile)
+ print (" NORMFLAT: Done.", >> logfile)
+ }
+}
diff --git a/noao/imred/generic/normflat.par b/noao/imred/generic/normflat.par
new file mode 100644
index 00000000..bec48aa3
--- /dev/null
+++ b/noao/imred/generic/normflat.par
@@ -0,0 +1,15 @@
+# NORMFLAT -- Make a flat field by normalizing and replacing low values.
+
+image,f,a,,,,Calibration image
+flatfield,f,a,,,,Flat field image
+norm,r,h,INDEF,,,Normalization if not INDEF
+minflat,r,h,INDEF,,,Minimum data value to use in the flat field
+sample_section,s,h,"[]",,,Sample section for determining normalization
+keeplog,b,h,)_.keeplog,,,Keep log of processing?
+logfile,f,h,)_.logfile,,,Log file
+img,f,h
+flt,f,h
+tmp,f,h
+rlist,*s,h
+mean,r,h
+stat,i,h
diff --git a/noao/imred/generic/x_generic.x b/noao/imred/generic/x_generic.x
new file mode 100644
index 00000000..f2a61e43
--- /dev/null
+++ b/noao/imred/generic/x_generic.x
@@ -0,0 +1 @@
+task flat1d