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 /pkg/obsolete | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/obsolete')
95 files changed, 28927 insertions, 0 deletions
diff --git a/pkg/obsolete/Revisions b/pkg/obsolete/Revisions new file mode 100644 index 00000000..f4a00d74 --- /dev/null +++ b/pkg/obsolete/Revisions @@ -0,0 +1,120 @@ +.help revisions Jan92 pkg.obsolete +.nf +===== +V2.12 +===== + +obsolete/obsolete.cl +obsolete/obsolete.men +obsolete/obsolete.hd +obsolete/x_obsolete.x +obsolete/mkpkg +obsolete/oimstatistics.par +obsolete/oimstat.h +obsolete/t_oimstat +obsolete/doc/oimstat.hlp + Added IMSTATISTICS from V2.11.3b. (8/30/01, Davis) + +obsolete/obsolete.cl +obsolete/obsolete.men +obsolete/obsolete.hd +obsolete/x_obsolete.x +obsolete/mkpkg +obsolete/oimcombine.par + +obsolete$doc/oimcombine.hlp + +obsolete$imcombine/ + + Added IMCOMBINE from V2.11.3b. (8/17/01, Valdes) + +obsolete/obsolete.cl +obsolete/obsolete.men +obsolete/obsolete.hd +obsolete/x_obsolete.x +obsolete/mkpkg +obsolete/odisplay.par - +obsolete$doc/odisplay.hlp - +obsolete$display/ - + Removed ODISPLAY task. (8/17/01, Valdes) + +======= +V2.11.3 +======= + +obsolete/obsolete.cl +obsolete/obsolete.men +obsolete/obsolete.hd +obsolete/x_obsolete.x +obsolete/mkpkg +obsolete/odisplay.par + +obsolete$doc/odisplay.hlp + +obsolete$display/ + + Moved the V2.10.4 versions of DISPLAY to OBSOLETE and renamed + it to ODISPLAY. (5/29/97, Valdes) + +obsolete/obsolete.cl +obsolete/obsolete.men +obsolete/obsolete.hd +obsolete/x_obsolete.x +obsolete/mkpkg +obsolete/orfits.par +obsolete/owfits.par +obsolete$doc/orfits.par +obsolete$doc/owfits.par +obsolete$fits/README +obsolete$fits/fits_cards.x +obsolete$fits/fits_params.x +obsolete$fits/fits_read.x +obsolete$fits/fits_rheader.x +obsolete$fits/fits_rimage.x +obsolete$fits/fits_rpixels.x +obsolete$fits/fits_wheader.x +obsolete$fits/fits_wimage.x +obsolete$fits/fits_wpixels.x +obsolete$fits/fits_write.x +obsolete$fits/mkpkg +obsolete$fits/ranges.x +obsolete$fits/rfits.com +obsolete$fits/rfits.h +obsolete$fits/structure.hlp +obsolete$fits/t_rfits.x +obsolete$fits/t_wfits.x +obsolete$fits/wfits.com +obsolete$fits/wfits.h + Moved the V2.10.4 versions of RFITS and WFITS to OBSOLETE and renamed + them to ORFITS and OWFITS. (5/29/97, Davis) + +obsolete$doc/ofixpix.hlp + Fixed errors in formating. (4/22/97, Valdes) + +obsolete$t_fixpix.x + +obsolete$fixcol.gx + +obsolete$t_fixline.gx + +obsolete$ofixpix.par + +obsolete$doc/ofixpix.hlp + +obsolete$mkpkg +obsolete$x_obsolete.x +obsolete$obsolete.cl +obsolete$obsolete.hd +obsolete$obsolete.men + Moved the V2.10.4 version of FIXPIX and renamed to OFIXPIX. + (6/14/96, Valdes) + +obsolete$<imcombine> - + The old imcombine task was removed. (6/14/96, Valdes) + +========= +V2.10.4p2 +========= + +obsolete$<imcombine> + The old imcombine task was added and renamed to oimcombine. + (1/30/92, Valdes) + +obsolete$* + + The obsolete package, PKG.OBSOLETE, was created. + + The tasks MKHISTOGRAM, IMTITLE, and RADPLT were moved out of the old + NOAO.PROTO package into the OBSOLETE package as they have been + superseded by the PHISTOGRAM, HEDIT, and PRADPROF tasks respectively. + + (1/23/92, Valdes Davis) +.endhelp diff --git a/pkg/obsolete/doc/imtitle.hlp b/pkg/obsolete/doc/imtitle.hlp new file mode 100644 index 00000000..36a1b296 --- /dev/null +++ b/pkg/obsolete/doc/imtitle.hlp @@ -0,0 +1,26 @@ +.help imtitle Aug84 obsolete +.ih +NAME +imtitle -- Change the title of an image +.ih +USAGE +imtitle image title +.ih +PARAMETERS +.ls image +Image to be modified. +.le +.ls title +New image title. +.le +.ih +DESCRIPTION +The title in \fIimage\fR is changed to \fItitle\fR. +.ih +EXAMPLES + + cl> imtitle m1 "M1 U Band" +.ih +USE INSTEAD +images.hedit +.endhelp diff --git a/pkg/obsolete/doc/mkhistogram.hlp b/pkg/obsolete/doc/mkhistogram.hlp new file mode 100644 index 00000000..3bd5e6ca --- /dev/null +++ b/pkg/obsolete/doc/mkhistogram.hlp @@ -0,0 +1,61 @@ +.help mkhistogram Feb88 obsolete +.ih +NAME +mkhistogram -- print or plot the histogram of a data stream +.ih +USAGE +mkhistogram file +.ih +PARAMETERS +.ls file +The name of the text file containing the data (may be STDIN). +.le +.ls nbins +The number of bins in the histogram. +.le +.ls z1 = INDEF, z2 = INDEF +The minimum and maximum histogram intensity. Z1 and z2 default to the data +minimum and maximum. +.le +.ls listout = yes +List instead of plot the histogram. +.le +.ls device = "stdgraph" +The output graphics device. +.le +.ih +DESCRIPTION +MKHISTOGRAM calculates the histogram of the data in the text +file \fIfile\fR using +the parameters \fInbins\fR, \fIz1\fR and \fIz2\fR. If the z1 or z2 are +undefined the image min or max is used. If \fIlistout\fR = no, the +histogram is plotted on the graphics device specified by \fIdevice\fR. +Otherwise the histogram is listed on the standard output. +.ih +EXAMPLES + +1. Output the histogram of data to a file. + +.nf + cl> mkhisto magsdata nbins=100 > magsdata.hst +.fi + +2. Plot the histogram of data between the 12.0 and 26.0 with a binsize + if 0.5 on standard graph. Notice that the extra bin will contain + points for which z2 is exactly 26. + +.nf + cl> mkhist magsdat nbins=29 z1=12.0 z2=26.0 li- +.fi + +.ih +TIME REQUIREMENTS +.ih +BUGS +.ih +USE INSTEAD +plot.phistogram +.ih +SEE ALSO +images.imhistogram, fields +.endhelp diff --git a/pkg/obsolete/doc/ofixpix.hlp b/pkg/obsolete/doc/ofixpix.hlp new file mode 100644 index 00000000..506dcbe6 --- /dev/null +++ b/pkg/obsolete/doc/ofixpix.hlp @@ -0,0 +1,85 @@ +.help ofixpix Jan85 proto +.ih +NAME +ofixpix -- fix bad pixels using a text file (from proto V2.10.4) +.ih +USAGE +.nf +ofixpix images badpixels +.fi +.ih +PARAMETERS +.ls image +List of two dimensional images to be modified. +.le +.ls badpixels +File containing the regions of bad pixels. A region is described by +four whitespace separated numbers consisting of the first and last columns +of the bad region and the first and last lines of the bad region. +.le +.ls verbose = no +Print the image names and the bad pixel regions? +.le +.ih +DESCRIPTION +Bad pixel regions in the list of two dimensional images are replaced by +linear interpolation using pixels bordering the bad pixel regions. +The bad pixel regions are input in the specified file consisting of lines +of coordinates (x1 x2 y1 y2) where x1 and x2 are the first and last columns +of the bad region and y1 and y2 are the first and last lines of the +bad region. The file may be STDIN to read from the standard input. +The type of interpolation is determined as follows: + +.ls (1) +If the bad region spans entire lines then the interpolation is from +neighboring lines. +.le +.ls (2) +If the bad region spans entire columns then the interpolation is from +neighboring columns. +.le +.ls (3) +If the bad region contains more lines than columns then the interpolation +is from neighboring columns. +.le +.ls (4) +If the bad region contains the same or more columns than lines then the +interpolation is from neighboring lines. +.le + +If the bad region borders the edge of the image then the interpolation +is by replication of the first good pixel in the direction of interpolation +and otherwise linear interpolation between the bordering lines or columns +is used. The verbose parameter may be used to produce of log of the pixel +modifications. +.ih +EXAMPLES +A detector has bad lines 10 and 25 to 27 and a partial bad column +at column 31 between lines 35 and 50. A bad region file is created containing +the lines + +.nf +1 100 10 10 +1 100 25 27 +31 31 35 50 +.fi + +The set of images "image*" are fixed by: + + cl> ofixpix image* badpixfile +.ih +REVISIONS +.ls OFIXPIX V2.11 +This is the V2.10.4 and earlier version of PROTO.FIXPIX. +.le +.ih +BUGS +This is a simple minded task which can be improved by using more sophisticated +interpolation. The bad pixel file will eventually be replaced by image +masks and bad pixel lists in the image. Be careful with image sections because +the bad pixel regions are relative to the image section. Also if the image +is trimmed or rotated then the bad pixel regions must be changed. +.ih +SEE ALSO +epix, imedit, fixpix +.endhelp diff --git a/pkg/obsolete/doc/oimcombine.hlp b/pkg/obsolete/doc/oimcombine.hlp new file mode 100644 index 00000000..adc95f83 --- /dev/null +++ b/pkg/obsolete/doc/oimcombine.hlp @@ -0,0 +1,1013 @@ +.help oimcombine May96 obsolete +.ih +NAME +oimcombine -- Combine images using various algorithms +.ih +USAGE +oimcombine input output +.ih +PARAMETERS +.ls input +List of input images to combine. All images must have the same dimensionality +but they may be of different sizes. +.le +.ls output +Output combined image or list of images. If the \fIproject\fR parameter is +no then there will be one output image while if it is yes there will be one +output image for each input image. +.le +.ls rejmask = "" (optional) +Output mask file to contain identifications of which pixels in which input +images were rejected or excluded. The pixel mask will be the size of the +output image and identified pixels will be in the output image pixel +coordinate system. There is on extra dimension with length equal to the +number of input images. Each element of this dimension contains the mask +of the input image. The order is the order of the input images. +.le +.ls plfile = "" (optional) +Output pixel list file or list of files. If no name is given or the +list ends prematurely then no file is produced. The pixel list file +is a map of the number of pixels rejected or, equivalently, +the total number of input images minus the number of pixels actually used. +The file name is also added to the output image header under the +keyword BPM. +.le +.ls sigma = "" (optional) +Output sigma image or list of images. If no name is given or the list ends +prematurely then no image is produced. The sigma is standard deviation, +corrected for a finite population, of the input pixel values (excluding +rejected pixels) about the output combined pixel values. +.le +.ls logfile = "STDOUT" (optional) +Output log file. If no file is specified then no log information is produced. +The special filename "STDOUT" prints log information to the terminal. +.le + +.ls combine = "average" (average|median) +Type of combining operation performed on the final set of pixels (after +offsetting, masking, thresholding, and rejection). The choices are +"average" or "median". The median uses the average of the two central +values when the number of pixels is even. +.le +.ls reject = "none" (none|minmax|ccdclip|crreject|sigclip|avsigclip|pclip) +Type of rejection operation performed on the pixels remaining after offsetting, +masking and thresholding. The algorithms are described in the +DESCRIPTION section. The rejection choices are: + +.nf + none - No rejection + minmax - Reject the nlow and nhigh pixels + ccdclip - Reject pixels using CCD noise parameters + crreject - Reject only positive pixels using CCD noise parameters + sigclip - Reject pixels using a sigma clipping algorithm + avsigclip - Reject pixels using an averaged sigma clipping algorithm + pclip - Reject pixels using sigma based on percentiles +.fi + +.le +.ls project = no +Project (combine) across the highest dimension of the input images? If +no then all the input images are combined to a single output image. If +yes then the highest dimension elements of each input image are combined to +an output image and optional pixel list and sigma images. Each element of +the highest dimension may have a separate offset but there can only be one +mask image. +.le +.ls outtype = "real" (short|ushort|integer|long|real|double) +Output image pixel datatype. The pixel datatypes are "double", "real", +"long", "integer", unsigned short "ushort", and "short" with highest +precedence first. If none is specified then the highest precedence +datatype of the input images is used. When there is a mixture of +short and unsigned short images the highest precedence become integer. +The datatypes may be abbreviated to +a single character. +.le +.ls offsets = "none" (none|wcs|grid|<filename>) +Integer offsets to add to each image axes. The options are: +.ls "none" +No offsets are applied. +.le +.ls "wcs" +The world coordinate system (wcs) in the image is used to derive the +offsets. The nearest integer offset that matches the world coordinate +at the center of the first input image is used. +.le +.ls "grid" +A uniform grid of offsets is specified by a string of the form + +.nf + grid [n1] [s1] [n2] [s2] ... +.fi + +where ni is the number of images in dimension i and si is the step +in dimension i. For example "grid 5 100 5 100" specifies a 5x5 +grid with origins offset by 100 pixels. +.le +.ls <filename> +The offsets are given in the specified file. The file consists +of one line per image with the offsets in each dimension forming the +columns. +.le +.le +.ls masktype = "none" (none|goodvalue|badvalue|goodbits|badbits) +Type of pixel masking to use. If "none" then no pixel masking is done +even if an image has an associated pixel mask. The other choices +are to select the value in the pixel mask to be treated as good +(goodvalue) or bad (badvalue) or the bits (specified as a value) +to be treated as good (goodbits) or bad (badbits). The pixel mask +file name comes from the image header keyword BPM. Note that when +combining images by projection of the highest dimension only one +pixel mask is applied to all the images. \fBNote\fR, if the number of +input images becomes too large (currently about 250 .imh or 125 .hhh +images) then the images are temporarily stacked and combined by projection +which also means the bad pixel mask from the first image will be used +for all images. +.le +.ls maskvalue = 0 +Mask value used with the \fImasktype\fR parameter. If the mask type +selects good or bad bits the value may be specified using IRAF notation +for decimal, octal, or hexadecimal; i.e 12, 14b, 0cx to select bits 3 +and 4. +.le +.ls blank = 0. +Output value to be used when there are no pixels. +.le + +.ls scale = "none" (none|mode|median|mean|exposure|@<file>|!<keyword>) +Multiplicative image scaling to be applied. The choices are none, multiply +by the reciprocal of the mode, median, or mean of the specified statistics +section, multiply by the reciprocal of the exposure time in the image header, +multiply by the values in a specified file, or multiply by a specified +image header keyword. When specified in a file the scales must be one per +line in the order of the input images. +.le +.ls zero = "none" (none|mode|median|mean|@<file>|!<keyword>) +Additive zero level image shifts to be applied. The choices are none, add +the negative of the mode, median, or mean of the specified statistics +section, add the values given in a file, or add the values given by an +image header keyword. When specified in a file the zero values must be one +per line in the order of the input images. File or keyword zero offset +values do not allow a correction to the weights. +.le +.ls weight = "none" (none|mode|median|mean|exposure|@<file>|!<keyword>) +Weights to be applied during the final averaging. The choices are none, +the mode, median, or mean of the specified statistics section, the exposure +time, values given in a file, or values given by an image header keyword. +When specified in a file the weights must be one per line in the order of +the input images and the only adjustment made by the task is for the number of +images previously combined. In this case the weights should be those +appropriate for the scaled images which would normally be the inverse +of the variance in the scaled image. +.le +.ls statsec = "" +Section of images to use in computing image statistics for scaling and +weighting. If no section is given then the entire region of the input is +sampled (for efficiency the images are sampled if they are big enough). +When the images are offset relative to each other one can precede the image +section with one of the modifiers "input", "output", "overlap". The first +interprets the section relative to the input image (which is equivalent to +not specifying a modifier), the second interprets the section relative to +the output image, and the last selects the common overlap and any following +section is ignored. +.le +.ls expname = "" +Image header keyword to be used with the exposure scaling and weighting +options. Also if an exposure keyword is specified that keyword will be +added to the output image using a weighted average of the input exposure +values. +.le + +.ce +Algorithm Parameters +.ls lthreshold = INDEF, hthreshold = INDEF +Low and high thresholds to be applied to the input pixels. This is done +before any scaling, rejection, and combining. If INDEF the thresholds +are not used. +.le +.ls nlow = 1, nhigh = 1 (minmax) +The number of low and high pixels to be rejected by the "minmax" algorithm. +These numbers are converted to fractions of the total number of input images +so that if no rejections have taken place the specified number of pixels +are rejected while if pixels have been rejected by masking, thresholding, +or nonoverlap, then the fraction of the remaining pixels, truncated +to an integer, is used. +.le +.ls nkeep = 1 +The minimum number of pixels to retain or the maximum number to reject +when using the clipping algorithms (ccdclip, crreject, sigclip, +avsigclip, or pclip). When given as a positive value this is the minimum +number to keep. When given as a negative value the absolute value is +the maximum number to reject. The latter is in addition to pixels +missing due to non-overlapping offsets, bad pixel masks, or thresholds. +.le +.ls mclip = yes (ccdclip, crreject, sigclip, avsigcliip) +Use the median as the estimate for the true intensity rather than the +average with high and low values excluded in the "ccdclip", "crreject", +"sigclip", and "avsigclip" algorithms? The median is a better estimator +in the presence of data which one wants to reject than the average. +However, computing the median is slower than the average. +.le +.ls lsigma = 3., hsigma = 3. (ccdclip, crreject, sigclip, avsigclip, pclip) +Low and high sigma clipping factors for the "ccdclip", "crreject", "sigclip", +"avsigclip", and "pclip" algorithms. They multiply a "sigma" factor +produced by the algorithm to select a point below and above the average or +median value for rejecting pixels. The lower sigma is ignored for the +"crreject" algorithm. +.le +.ls rdnoise = "0.", gain = "1.", snoise = "0." (ccdclip, crreject) +CCD readout noise in electrons, gain in electrons/DN, and sensitivity noise +as a fraction. These parameters are used with the "ccdclip" and "crreject" +algorithms. The values may be either numeric or an image header keyword +which contains the value. The noise model for a pixel is: + +.nf + variance in DN = (rdnoise/gain)^2 + DN/gain + (snoise*DN)^2 + variance in e- = (rdnoise)^2 + (gain*DN) + (snoise*(gain*DN))^2 + = rdnoise^2 + Ne + (snoise * Ne)^2 +.fi + +where DN is the data number and Ne is the number of electrons. Sensitivity +noise typically comes from noise introduced during flat fielding. +.le +.ls sigscale = 0.1 (ccdclip, crreject, sigclip, avsigclip) +This parameter determines when poisson corrections are made to the +computation of a sigma for images with different scale factors. If all +relative scales are within this value of unity and all relative zero level +offsets are within this fraction of the mean then no correction is made. +The idea is that if the images are all similarly though not identically +scaled, the extra computations involved in making poisson corrections for +variations in the sigmas can be skipped. A value of zero will apply the +corrections except in the case of equal images and a large value can be +used if the sigmas of pixels in the images are independent of scale and +zero level. +.le +.ls pclip = -0.5 (pclip) +Percentile clipping algorithm parameter. If greater than +one in absolute value then it specifies a number of pixels above or +below the median to use for computing the clipping sigma. If less +than one in absolute value then it specifies the fraction of the pixels +above or below the median to use. A positive value selects a point +above the median and a negative value selects a point below the median. +The default of -0.5 selects approximately the quartile point. +See the DESCRIPTION section for further details. +.le +.ls grow = 0. +Radius in pixels for additional pixel to be rejected in an image with a +rejected pixel from one of the rejection algorithms. This applies only to +pixels rejected by one of the rejection algorithms and not the masked or +threshold rejected pixels. +.le +.ih +DESCRIPTION +A set of images or the highest dimension elements (for example the planes +in an image cube) are combined by weighted averaging or medianing. Pixels +may be rejected from the combining by using pixel masks, threshold levels, +and rejection algorithms. The images may be scaled multiplicatively or +additively based on image statistics, image header keywords, or text files +before rejection. The images may be combined with integer pixel coordinate +offsets, possibly determined using the world coordinate system of the +images, to produce an image bigger than any of the input images. + +The input images to be combined are specified by a list. If the +\fBproject\fR parameter is yes then the highest dimension elements of each +input image are combined to make an output image of one lower dimension. +There is no limit to the number of elements combined in this case. If +\fBproject\fR is no then the entire input list is combined to form a single +output image. In this case the images must all have the same +dimensionality but they may have different sizes. There is a software +limit of approximately 100 images in this case. + +The output image header is a copy of the first image in the combined set. +In addition, the number of images combined is recorded under the keyword +NCOMBINE, an image header keyword selected by the \fIexpname\fR parameters +(which is usually an exposure time) is updated as the weighted average of +the input header keywords, and any pixel list file created is recorded +under the keyword BPM. The output pixel type is set by the parameter +\fIouttype\fR. If left blank then the input datatype of highest precision +is used. If there is a mixture of short and unsigned short images then +the highest precision is integer. + +In addition to one or more output combined images there are some optional +output files which may be specified. A pixel mask identifying each pixel +rejected or excluded may be created. This mask will match the output +image in size except there is one extra dimension. The extra dimension +indexes the input images in the order in which they are specified and +combined. What this means is that each element of the extra dimension +is a mask of the pixel rejected in a particular input image (or lower +dimensional element in the case of projection) but in the offset and +sized to the output image. For example, if the input consists of +two dimensional images then the rejected pixel mask will be three +dimensional and each plane will be for a particular input image. +If one wants to separate this file the task \fBimslice\fR may be used. +If there are no offsets then the masks will also be registered with the +input image. If there are offsets then the masks will be offset +also. + +Another pixel mask may be produced giving just the total number of pixels +rejected at each output pixel. An image containing the sigmas of the +pixels combined about the final output combined pixels may also be +created. The sigma computation is the standard deviation corrected for a +finite population (the n/(n-1) factor) including weights if a weighted +average is used. Finally a log file may be produced. + +An outline of the steps taken by the program is given below and the +following sections elaborate on the steps. + +.nf +o Set the input image offsets and the final output image size. +o Set the input image scales and weights +o Write the log file output +.fi + +For each output image line: + +.nf +o Get input image lines that overlap the output image line +o Reject masked pixels +o Reject pixels outside the threshold limits +o Reject pixels using the specified algorithm +o Reject neighboring pixels along each line +o Combine remaining pixels using the weighted average or median +o Compute sigmas of remaining pixels about the combined values +o Write the output image line, rejected pixel masks, and sigmas +.fi + + +OFFSETS + +The images to be combined need not be of the same size or overlap. They +do have to have the same dimensionality which will also be the dimensionality +of the output image. Any dimensional images supported by IRAF may be +used. Note that if the \fIproject\fR flag is yes then the input images +are the elements of the highest dimension; for example the planes of a +three dimensional image. + +The overlap of the images is determined by a set of integer pixel offsets +with an offset for each dimension of each input image. For example +offsets of 0, 10, and 20 in the first dimension of three images will +result in combining the three images with only the first image in the +first 10 columns, the first two images in the next 10 columns and +all three images starting in the 21st column. At the 21st output column +the 21st column of the first image will be combined with the 11th column +of the second image and the 1st column of the third image. + +The output image size is set by the maximum extent in each dimension +of any input image after applying the offsets. In the above example if +all the images have 100 columns then the output image will have 120 +columns corresponding to the 20 column offset in the third image. + +The input image offsets are set using the \fIoffset\fR parameter. There +are four ways to specify the offsets. If the word "none" or the empty +string "" are used then all offsets will be zero and all pixels with the +same coordinates will be combined. The output image size will be equal to +the biggest dimensions of the input images. + +If "wcs" offsets are specified then the world coordinate systems (wcs) +in the image headers are used to derived the offsets. The world coordinate +at the center of the first input image is evaluated. Then integer pixel +offsets are determined for each image to bring the same world coordinate +to the same point. Note the following caveats. The world coordinate +systems must be of the same type, orientation, and scale and only the +nearest integer shift is used. + +If the input images have offsets in a regular grid or one wants to make +an output image in which the input images are "mosaiced" together in +a grid then the special offset string beginning with the word "grid" +is used. The format is + +.nf + grid [n1] [s1] [n2] [s2] ... +.fi + +where ni is the number of images in dimension i and si is the step in +dimension i. For example "grid 5 100 5 100" specifies a 5x5 grid with +origins offset by 100 pixels. Note that one must insure that the input +images are specified in the correct order. This may best be accomplished +using a "@" list. One useful application of the grid is to make a +nonoverlapping mosaic of a number of images for display purposes. Suppose +there are 16 images which are 100x100. The offset string "grid 4 101 4 +101" will produce a mosaic with a one pixel border having the value set +by \fIblank\fR parameter between the images. + +The offsets may be defined in a file by specifying the file name +in the \fIoffset\fR parameter. (Note that the special file name STDIN +may be used to type in the values terminated by the end-of-file +character). The file consists of a line for each input image. The lines +must be in the same order as the input images and so an "@" list may +be useful. The lines consist of whitespace separated offsets one for +each dimension of the images. In the first example cited above the +offset file might contain: + +.nf + 0 0 + 10 0 + 20 0 +.fi + +where we assume the second dimension has zero offsets. + +The offsets need not have zero for one of the images. The offsets may +include negative values or refer to some arbitrary common point. +When the offsets are read by the program it will find the minimum +value in each dimension and subtract it from all the other offsets +in that dimension. The above example could also be specified as: + +.nf + 225 15 + 235 15 + 245 15 +.fi + +There may be cases where one doesn't want the minimum offsets reset +to zero. If all the offsets are positive and the comment "# Absolute" +appears in the offset file then the images will be combined with +blank values between the first output pixel and the first overlapping +input pixel. Continuing with the above example, the file + +.nf + # Absolute + 10 10 + 20 10 + 30 10 +.fi + +will have the first pixel of the first image in the 11th pixel of the +output image. Note that there is no way to "pad" the other side of +the output image. + + +SCALES AND WEIGHTS + +In order to combine images with rejection of pixels based on deviations +from some average or median they must be scaled to a common level. There +are two types of scaling available, a multiplicative intensity scale and an +additive zero point shift. The intensity scaling is defined by the +\fIscale\fR parameter and the zero point shift by the \fIzero\fR +parameter. These parameters may take the values "none" for no scaling, +"mode", "median", or "mean" to scale by statistics of the image pixels, +"exposure" (for intensity scaling only) to scale by the exposure time +keyword in the image header, any other image header keyword specified by +the keyword name prefixed by the character '!', and the name of a file +containing the scale factors for the input image prefixed by the +character '@'. + +Examples of the possible parameter values are shown below where +"myval" is the name of an image header keyword and "scales.dat" is +a text file containing a list of scale factors. + +.nf + scale = none No scaling + zero = mean Intensity offset by the mean + scale = exposure Scale by the exposure time + zero = !myval Intensity offset by an image keyword + scale = @scales.dat Scales specified in a file +.fi + +The image statistics are computed by sampling a uniform grid of points with +the smallest grid step that yields less than 10000 pixels; sampling is used +to reduce the time needed to compute the statistics. If one wants to +restrict the sampling to a region of the image the \fIstatsec\fR parameter +is used. This parameter has the following syntax: + +.nf + [input|output|overlap] [image section] +.fi + +The initial modifier defaults to "input" if absent. The modifiers are useful +if the input images have offsets. In that case "input" specifies +that the image section refers to each input image, "output" specifies +that the image section refers to the output image coordinates, and +"overlap" specifies the mutually overlapping region of the input images. +In the latter case an image section is ignored. + +The statistics are as indicated by their names. In particular, the +mode is a true mode using a bin size which is a fraction of the +range of the pixels and is not based on a relationship between the +mode, median, and mean. Also masked pixels are excluded from the +computations as well as during the rejection and combining operations. + +The "exposure" option in the intensity scaling uses the value of the +image header keyword specified by the \fIexpname\fR keyword. As implied +by the parameter name, this is typically the image exposure time since +intensity levels are linear with the exposure time in CCD detectors. +Note that the exposure keyword is also updated in the final image +as the weighted average of the input values. Thus, if one wants to +use a nonexposure time keyword and keep the exposure time updating +feature the image header keyword syntax is available; i.e. !<keyword>. + +Scaling values may be defined as a list of values in a text file. The file +name is specified by the standard @file syntax. The list consists of one +value per line. The order of the list is assumed to be the same as the +order of the input images. It is a fatal error if the list is incomplete +and a warning if the list appears longer than the number of input images. +Because the scale and zero levels are adjusted only the relative +values are important. + +If both an intensity scaling and zero point shift are selected the +zero point is added first and the scaling is done. This is +important if the scale and offset values are specified by +header keywords or from a file of values. However, +in the log output the zero values are given as the scale times +the offset hence those numbers would be interpreted as scaling +first and zero offset second. + +The image statistics and scale factors are recorded in the log file +unless they are all equal, which is equivalent to no scaling. The +intensity scale factors are normalized to a unit mean and the zero +point shifts are adjust to a zero mean. When scale factors or +zero point shifts are specified by the user in an @file or +by an image header keyword no normalization is done. + +Scaling affects not only the mean values between images but also the +relative pixel uncertainties. For example scaling an image by a +factor of 0.5 will reduce the effective noise sigma of the image +at each pixel by the square root of 0.5. Changes in the zero +point also changes the noise sigma if the image noise characteristics +are Poissonian. In the various rejection algorithms based on +identifying a noise sigma and clipping large deviations relative to +the scaled median or mean, one may need to account for the scaling induced +changes in the image noise characteristics. + +In those algorithms it is possible to eliminate the "sigma correction" +while still using scaling. The reasons this might be desirable are 1) if +the scalings are similar the corrections in computing the mean or median +are important but the sigma corrections may not be important and 2) the +image statistics may not be Poissonian, either inherently or because the +images have been processed in some way that changes the statistics. In the +first case because computing square roots and making corrections to every +pixel during the iterative rejection operation may be a significant +computational speed limit the parameter \fIsigscale\fR selects how +dissimilar the scalings must be to require the sigma corrections. This +parameter is a fractional deviation which, since the scale factors are +normalized to unity, is the actual minimum deviation in the scale factors. +For the zero point shifts the shifts are normalized by the mean shift +before adjusting the shifts to a zero mean. To always use sigma scaling +corrections the parameter is set to zero and to eliminate the correction in +all cases it is set to a very large number. + +If the final combining operation is "average" then the images may be +weighted during the averaging. The weights are specified in the +same way as the scale factors. In addition +the NCOMBINE keyword, if present, will be used in the weights. +The weights, scaled to a unit sum, are printed in the log output. + +The weights are only used for the final weighted average and sigma image +output. They are not used to form averages in the various rejection +algorithms. For weights in the case of no scaling or only multiplicative +scaling the weights are used as given or determined so that images with +lower signal levels will have lower weights. However, for cases in which +zero level scaling is used and the zero levels are determined from image +statistics (not from an input file or keyword) the weights are computed +from the initial weights (the exposure time, image statistics, or input +values) using the formula: + +.nf + weight_final = weight_initial / (scale * sky) +.fi + +where the sky values are those from the image statistics before conversion +to zero level shifts and adjustment to zero mean over all images. The +reasoning is that if the zero level is high the sky brightness is high and +so the S/N is lower and the weight should be lower. If any sky value +determined from the image statistics comes out to be negative a warning is +given and the none of the weight are adjusted for sky levels. + +The weights are not adjusted when the zero offsets are input from a file +or keyword since these values do not imply the actual image sky value. +In this case if one wants to account for different sky statistics +in the weights the user must specify the weights in a file taking +explicit account of changes in the weights due to different sky +statistics. + + +PIXEL MASKS + +A pixel mask is a type of IRAF file having the extension ".pl" which +identifies an integer value with each pixel of the images to which it is +applied. The integer values may denote regions, a weight, a good or bad +flag, or some other type of integer or integer bit flag. In the common +case where many values are the same this file is compacted to be small and +efficient to use. It is also most compact and efficient if the majority of +the pixels have a zero mask value so frequently zero is the value for good +pixels. Note that these files, while not stored as a strict pixel array, +may be treated as images in programs. This means they may be created by +programs such as \fBmkpattern\fR, edited by \fBimedit\fR, examined by +\fBimexamine\fR, operated upon by \fBimarith\fR, graphed by \fBimplot\fR, +and displayed by \fBdisplay\fR. + +At the time of introducing this task, generic tools for creating +pixel masks have yet to be written. There are two ways to create a +mask in V2.10. First if a regular integer image can be created +then it can be converted to pixel list format with \fBimcopy\fR: + +.nf + cl> imcopy template plfile.pl +.fi + +by specifically using the .pl extension on output. Other programs that +can create integer images (such \fBmkpattern\fR or \fBccdred.badpiximage\fR) +can create the pixel list file directly by simply using the ".pl" +extension in the output image name. + +To use pixel masks with \fBoimcombine\fR one must associate a pixel +mask file with an image by entering the pixel list file name in the +image header under the keyword BPM (bad pixel mask). This can be +done with \fBhedit\fR. Note that the same pixel mask may be associated +with more than one image as might be the case if the mask represents +defects in the detector used to obtain the images. + +If a pixel mask is associated with an image the mask is used when the +\fImasktype\fR parameter is set to a value other than "none". Note that +when it is set to "none" mask information is not used even if it exists for +the image. The values of \fImasktype\fR which apply masks are "goodvalue", +"badvalue", "goodbits", and "badbits". They are used in conjunction with +the \fImaskvalue\fR parameter. When the mask type is "goodvalue" the +pixels with mask values matching the specified value are included in +combining and all others are rejected. Similarly, for a mask type of +"badvalue" the pixels with mask values matching the specified value are +rejected and all others are accepted. The bit types are useful for +selecting a combination of attributes in a mask consisting of bit flags. +The mask value is still an integer but is interpreted by bitwise comparison +with the values in the mask file. + +If a mask operation is specified and an image has no mask image associated +with it then the mask values are taken as all zeros. In those cases be +careful that zero is an accepted value otherwise the entire image will be +rejected. + +In the case of combining the higher dimensions of an image into a +lower dimensional image, the "project" option, the same pixel mask +is applied to all of the data being combined; i.e. the same 2D +pixel mask is applied to every plane of a 3D image. This is because +a higher dimensional image is treated as a collection of lower +dimensional images having the same header and hence the same +bad pixel mask. It would be tempting to use a bad pixel mask with +the same dimension as the image being projected but this is not +currently how the task works. + +When the number of input images exceeds the maximum number of open files +allowed by IRAF (currently about 250 or 125 .hhh images) the input images +are stacked and combined with the \fIproject\fR option. \fBNote\fR that +this means that the bad pixel mask from the first input image will be +applied to all the images. + + +THRESHOLD REJECTION + +In addition to rejecting masked pixels, pixels in the unscaled input +images which are below or above the thresholds given by the parameters +\fIlthreshold\fR and \fIhthreshold\fR are rejected. Values of INDEF +mean that no threshold value is applied. Threshold rejection may be used +to exclude very bad pixel values or as an alternative way of masking +images. In the latter case one can use a task like \fBimedit\fR +or \fBimreplace\fR to set parts of the images to be excluded to some +very low or high magic value. + + +REJECTION ALGORITHMS + +The \fIreject\fR parameter selects a type of rejection operation to +be applied to pixels not masked or thresholded. If no rejection +operation is desired the value "none" is specified. + +MINMAX +.in 4 +A specified fraction of the highest and lowest pixels are rejected. +The fraction is specified as the number of high and low pixels, the +\fInhigh\fR and \fInlow\fR parameters, when data from all the input images +are used. If pixels have been rejected by offsetting, masking, or +thresholding then a matching fraction of the remaining pixels, truncated +to an integer, are used. Thus, + +.nf + nl = n * nlow/nimages + 0.001 + nh = n * nhigh/nimages + 0.001 +.fi + +where n is the number of pixels surviving offsetting, masking, and +thresholding, nimages is the number of input images, nlow and nhigh +are task parameters and nl and nh are the final number of low and +high pixels rejected by the algorithm. The factor of 0.001 is to +adjust for rounding of the ratio. + +As an example with 10 input images and specifying one low and two high +pixels to be rejected the fractions to be rejected are nlow=0.1 and nhigh=0.2 +and the number rejected as a function of n is: + +.nf + n 0 1 2 3 4 5 6 7 8 9 10 + nl 0 0 0 0 0 0 0 0 0 0 1 + nh 0 0 0 0 0 1 1 1 1 1 2 +.fi + +.in -4 +CCDCLIP +.in 4 +If the images are obtained using a CCD with known read out noise, gain, and +sensitivity noise parameters and they have been processed to preserve the +relation between data values and photons or electrons then the noise +characteristics of the images are well defined. In this model the sigma in +data values at a pixel with true value <I>, as approximated by the median +or average with the lowest and highest value excluded, is given by: + +.nf + sigma = ((rn / g) ** 2 + <I> / g + (s * <I>) ** 2) ** 1/2 +.fi + +where rn is the read out noise in electrons, g is the gain in +electrons per data value, s is a sensitivity noise given as a fraction, +and ** is the exponentiation operator. Often the sensitivity noise, +due to uncertainties in the pixel sensitivities (for example from the +flat field), is not known in which case a value of zero can be used. +See the task \fBstsdas.wfpc.noisemodel\fR for a way to determine +these values (though that task expresses the read out noise in data +numbers and the sensitivity noise parameter as a percentage). + +The read out noise is specified by the \fIrdnoise\fR parameter. The value +may be a numeric value to be applied to all the input images or a image +header keyword containing the value for each image. Similarly, the +parameter \fIgain\fR specifies the gain as either a value or image header +keyword and the parameter \fIsnoise\fR specifies the sensitivity +noise parameter as either a value or image header keyword. + +The algorithm operates on each output pixel independently. It starts by +taking the median or unweighted average (excluding the minimum and maximum) +of the unrejected pixels provided there are at least two input pixels. The +expected sigma is computed from the CCD noise parameters and pixels more +that \fIlsigma\fR times this sigma below or \fIhsigma\fR times this sigma +above the median or average are rejected. The process is then iterated +until no further pixels are rejected. If the average is used as the +estimator of the true value then after the first round of rejections the +highest and lowest values are no longer excluded. Note that it is possible +to reject all pixels if the average is used and is sufficiently skewed by +bad pixels such as cosmic rays. + +If there are different CCD noise parameters for the input images +(as might occur using the image header keyword specification) then +the sigmas are computed for each pixel from each image using the +same estimated true value. + +If the images are scaled and shifted and the \fIsigscale\fR threshold +is exceedd then a sigma is computed for each pixel based on the +image scale parameters; i.e. the median or average is scaled to that of the +original image before computing the sigma and residuals. + +After rejection the number of retained pixels is checked against the +\fInkeep\fR parameter. If there are fewer pixels retained than specified +by this parameter the pixels with the smallest residuals in absolute +value are added back. If there is more than one pixel with the same +absolute residual (for example the two pixels about an average +or median of two will have the same residuals) they are all added +back even if this means more than \fInkeep\fR pixels are retained. +Note that the \fInkeep\fR parameter only applies to the pixels used +by the clipping rejection algorithm and does not apply to threshold +or bad pixel mask rejection. + +This is the best clipping algorithm to use if the CCD noise parameters are +adequately known. The parameters affecting this algorithm are \fIreject\fR +to select this algorithm, \fImclip\fR to select the median or average for +the center of the clipping, \fInkeep\fR to limit the number of pixels +rejected, the CCD noise parameters \fIrdnoise, gain\fR and \fIsnoise\fR, +\fIlsigma\fR and \fIhsigma\fR to select the clipping thresholds, +and \fIsigscale\fR to set the threshold for making corrections to the sigma +calculation for different image scale factors. + +.in -4 +CRREJECT +.in 4 +This algorithm is identical to "ccdclip" except that only pixels above +the average are rejected based on the \fIhsigma\fR parameter. This +is appropriate for rejecting cosmic ray events and works even with +two images. + +.in -4 +SIGCLIP +.in 4 +The sigma clipping algorithm computes at each output pixel the median or +average excluding the high and low values. The sigma is then computed +about this estimate (without excluding the low and high values). There +must be at least three input pixels, though for this method to work well +there should be at least 10 pixels. Values deviating by more than the +specified sigma threshold factors are rejected. These steps are repeated, +except that after the first time the average includes all values, until no +further pixels are rejected or there are fewer than three pixels. + +After rejection the number of retained pixels is checked against the +\fInkeep\fR parameter. If there are fewer pixels retained than specified +by this parameter the pixels with the smallest residuals in absolute +value are added back. If there is more than one pixel with the same +absolute residual (for example the two pixels about an average +or median of two will have the same residuals) they are all added +back even if this means more than \fInkeep\fR pixels are retained. +Note that the \fInkeep\fR parameter only applies to the pixels used +by the clipping rejection algorithm and does not apply to threshold +or bad pixel mask rejection. + +The parameters affecting this algorithm are \fIreject\fR to select +this algorithm, \fImclip\fR to select the median or average for the +center of the clipping, \fInkeep\fR to limit the number of pixels +rejected, \fIlsigma\fR and \fIhsigma\fR to select the +clipping thresholds, and \fIsigscale\fR to set the threshold for +making corrections to the sigma calculation for different image scale +factors. + +.in -4 +AVSIGCLIP +.in 4 +The averaged sigma clipping algorithm assumes that the sigma about the +median or mean (average excluding the low and high values) is proportional +to the square root of the median or mean at each point. This is +described by the equation: + +.nf + sigma(column,line) = sqrt (gain(line) * signal(column,line)) +.fi + +where the \fIestimated\fR signal is the mean or median (hopefully excluding +any bad pixels) and the gain is the \fIestimated\fR proportionality +constant having units of photons/data number. + +This noise model is valid for images whose values are proportional to the +number of photons recorded. In effect this algorithm estimates a +detector gain for each line with no read out noise component when +information about the detector noise parameters are not known or +available. The gain proportionality factor is computed +independently for each output line by averaging the square of the residuals +(at points having three or more input values) scaled by the median or +mean. In theory the proportionality should be the same for all rows but +because of the estimating process will vary somewhat. + +Once the proportionality factor is determined, deviant pixels exceeding the +specified thresholds are rejected at each point by estimating the sigma +from the median or mean. If any values are rejected the median or mean +(this time not excluding the extreme values) is recomputed and further +values rejected. This is repeated until there are no further pixels +rejected or the number of remaining input values falls below three. Note +that the proportionality factor is not recomputed after rejections. + +If the images are scaled differently and the sigma scaling correction +threshold is exceedd then a correction is made in the sigma +calculations for these differences, again under the assumption that +the noise in an image scales as the square root of the mean intensity. + +After rejection the number of retained pixels is checked against the +\fInkeep\fR parameter. If there are fewer pixels retained than specified +by this parameter the pixels with the smallest residuals in absolute +value are added back. If there is more than one pixel with the same +absolute residual (for example the two pixels about an average +or median of two will have the same residuals) they are all added +back even if this means more than \fInkeep\fR pixels are retained. +Note that the \fInkeep\fR parameter only applies to the pixels used +by the clipping rejection algorithm and does not apply to threshold +or bad pixel mask rejection. + +This algorithm works well for even a few input images. It works better if +the median is used though this is slower than using the average. Note that +if the images have a known read out noise and gain (the proportionality +factor above) then the "ccdclip" algorithm is superior. The two algorithms +are related in that the average sigma proportionality factor is an estimate +of the gain. + +The parameters affecting this algorithm are \fIreject\fR to select +this algorithm, \fImclip\fR to select the median or average for the +center of the clipping, \fInkeep\fR to limit the number of pixels +rejected, \fIlsigma\fR and \fIhsigma\fR to select the +clipping thresholds, and \fIsigscale\fR to set the threshold for +making corrections to the sigma calculation for different image scale +factors. + +.in -4 +PCLIP +.in 4 +The percentile clipping algorithm is similar to sigma clipping using the +median as the center of the distribution except that, instead of computing +the sigma of the pixels from the CCD noise parameters or from the data +values, the width of the distribution is characterized by the difference +between the median value and a specified "percentile" pixel value. This +width is then multiplied by the scale factors \fIlsigma\fR and \fIhsigma\fR +to define the clipping thresholds above and below the median. The clipping +is not iterated. + +The pixel values at each output point are ordered in magnitude and the +median is determined. In the case of an even number of pixels the average +of the two middle values is used as the median value and the lower or upper +of the two is the median pixel when counting from the median pixel to +selecting the percentile pixel. The parameter \fIpclip\fR selects the +percentile pixel as the number (if the absolute value is greater +than unity) or fraction of the pixels from the median in the ordered set. +The direction of the percentile pixel from the median is set by the sign of +the \fIpclip\fR parameter with a negative value signifying pixels with +values less than the median. Fractional values are internally converted to +the appropriate number of pixels for the number of input images. A minimum +of one pixel and a maximum corresponding to the extreme pixels from the +median are enforced. The value used is reported in the log output. Note +that the same percentile pixel is used even if pixels have been rejected by +offsetting, masking, or thresholding; for example, if the 3rd pixel below +the median is specified then the 3rd pixel will be used whether there are +10 pixels or 5 pixels remaining after the preliminary steps. + +After rejection the number of retained pixels is checked against the +\fInkeep\fR parameter. If there are fewer pixels retained than specified +by this parameter the pixels with the smallest residuals in absolute +value are added back. If there is more than one pixel with the same +absolute residual (for example the two pixels about an average +or median of two will have the same residuals) they are all added +back even if this means more than \fInkeep\fR pixels are retained. +Note that the \fInkeep\fR parameter only applies to the pixels used +by the clipping rejection algorithm and does not apply to threshold +or bad pixel mask rejection. + +Some examples help clarify the definition of the percentile pixel. In the +examples assume 10 pixels. The median is then the average of the +5th and 6th pixels. A \fIpclip\fR value of 2 selects the 2nd pixel +above the median (6th) pixel which is the 8th pixel. A \fIpclip\fR +value of -0.5 selects the point halfway between the median and the +lowest pixel. In this case there are 4 pixels below the median, +half of that is 2 pixels which makes the percentile pixel the 3rd pixel. + +The percentile clipping algorithm is most useful for clipping small +excursions, such as the wings of bright objects when combining +disregistered observations for a sky flat field, that are missed when using +the pixel values to compute a sigma. It is not as powerful, however, as +using the CCD noise parameters (provided they are accurately known) to clip +about the median. + +The parameters affecting this algorithm are \fIreject\fR to select this +algorithm, \fIpclip\fR to select the percentile pixel, \fInkeep\fR to limit +the number of pixels rejected, and \fIlsigma\fR and \fIhsigma\fR to select +the clipping thresholds. + +.in -4 +GROW REJECTION + +Neighbors of pixels rejected by the rejection algorithms +may also be rejected. The number of neighbors to be rejected +is specified by the \fIgrow\fR parameter which is a radius in pixels. +If too many pixels are rejected in one of the grown pixels positions +(as defined by the \fInkeep\fR parameter) then the value of that pixel +without growing will be used. + +COMBINING + +After all the steps of offsetting the input images, masking pixels, +threshold rejection, scaling, and applying a rejection algorithms the +remaining pixels are combined and output. The pixels may be combined +by computing the median or by computing a weighted average. + + +SIGMA OUTPUT + +In addition to the combined image and optional sigma image may be +produced. The sigma computed is the standard deviation, corrected for a +finite population by a factor of n/(n-1), of the unrejected input pixel +values about the output combined pixel values. +.ih +EXAMPLES +1. To average and median images without any other features: + +.nf + cl> oimcombine obj* avg combine=average reject=none + cl> oimcombine obj* med combine=median reject=none +.fi + +2. To reject cosmic rays: + +.nf + cl> oimcombine obs1,obs2 Obs reject=crreject rdnoise=5.1, gain=4.3 +.fi + +3. To make a grid for display purposes with 21 64x64 images: + +.nf + cl> oimcombine @list grid offset="grid 5 65 5 65" +.fi + +4. To apply a mask image with good pixels marked with a zero value and +bad pixels marked with a value of one: + +.nf + cl> hedit ims* bpm badpix.pl add+ ver- + cl> oimcombine ims* final combine=median masktype=goodval +.fi + +5. To scale image by the exposure time and then adjust for varying +sky brightness and make a weighted average: + +.nf + cl> oimcombine obj* avsig combine=average reject=avsig \ + >>> scale=exp zero=mode weight=exp expname=exptime +.fi +.ih +REVISIONS +.ls OIMCOMBINE V2.11.4 +The version of IMCOMBINE from V2.11-V2.11.3 was moved to OBSOLETE. +.le +.ih +LIMITATIONS +Though the previous limit on the number of images that can be combined +was removed in V2.11 the method has the limitation that only a single +bad pixel mask will be used for all images. +.ih +SEE ALSO +immatch.imcombine ccdred.combine onedspec.scombine, wpfc.noisemodel +.endhelp diff --git a/pkg/obsolete/doc/oimstat.hlp b/pkg/obsolete/doc/oimstat.hlp new file mode 100644 index 00000000..2dd23de2 --- /dev/null +++ b/pkg/obsolete/doc/oimstat.hlp @@ -0,0 +1,108 @@ +.help oimstatistics Jan90 images.imutil +.ih +NAME +oimstatistics -- compute and print image pixel statistics +.ih +USAGE +oimstatistics images +.ih +PARAMETERS +.ls images +Images for which pixel statistics are to be computed. +.le +.ls fields = "image,npix,mean,stddev,min,max" +The statistical quantities to be computed and printed. +.le +.ls lower = INDEF +Use only pixels with values greater than or equal to this limit. +All pixels are above the default value of INDEF. +.le +.ls upper = INDEF +Use only pixels with values less than or equal to this limit. +All pixels are below the default value of INDEF. +.le +.ls binwidth = 0.1 +The width of the histogram bins used for computing the midpoint (estimate +of the median) and the mode. +The units are in sigma. +.le +.ls format = yes +Label the output columns and print the result in fixed format. If format +is "no" no column labels are printed and the output is in free format. +.le +.ih +DESCRIPTION +The statistical quantities specified by the parameter \fIfields\fR are +computed and printed for each image in the list specified by \fIimages\fR. +The results are printed in tabular form with the fields listed in the order +they are specified in the fields parameter. The available fields are the +following. + +.nf + image - the image name + npix - the number of pixels used to do the statistics + mean - the mean of the pixel distribution + midpt - estimate of the median of the pixel distribution + mode - the mode of the pixel distribution + stddev - the standard deviation of the pixel distribution + skew - the skew of the pixel distribution + kurtosis - the kurtosis of the pixel distribution + min - the minimum pixel value + max - the maximum pixel value +.fi + +The mean, standard deviation, skew, kurtosis, min and max are computed in a +single pass through the image using the expressions listed below. +Only the quantities selected by the fields parameter are actually computed. + +.nf + mean = sum (x1,...,xN) / N + y = x - mean + variance = sum (y1 ** 2,...,yN ** 2) / (N-1) + stddev = sqrt (variance) + skew = sum ((y1 / stddev) ** 3,...,(yN / stddev) ** 3) / (N-1) + kurtosis = sum ((y1 / stddev) ** 4,...,(yN / stddev) ** 4) / (N-1) - 3 +.fi + +The midpoint and mode are computed in two passes through the image. In the +first pass the standard deviation of the pixels is calculated and used +with the \fIbinwidth\fR parameter to compute the resolution of the data +histogram. The midpoint is estimated by integrating the histogram and +computing by interpolation the data value at which exactly half the +pixels are below that data value and half are above it. The mode is +computed by locating the maximum of the data histogram and fitting the +peak by parabolic interpolation. + +.ih +EXAMPLES +1. To find the number of pixels, mean, standard deviation and the minimum +and maximum pixel value of a bias region in an image. + +.nf + cl> oimstat flat*[*,1] + # IMAGE NPIX MEAN STDDEV MIN MAX + flat1[*,1] 800 999.5 14.09 941. 1062. + flat2[*,1] 800 999.4 28.87 918. 1413. +.fi + +The string "flat*" uses a wildcard to select all images beginning with the +word flat. The string "[*,1]" is an image section selecting row 1. + +2. Compute the mean, midpoint, mode and standard deviation of a pixel +distribution. + +.nf + cl> oimstat m51 fields="image,mean,midpt,mode,stddev" + # IMAGE PIXELS MEAN MIDPT MODE STDDEV + M51 262144 108.3 88.75 49.4 131.3 +.fi + +.ih +BUGS +When using a very large number of pixels the accumulation of the sums +of the pixel values to the various powers may +encounter roundoff error. This is significant when the true standard +deviation is small compared to the mean. +.ih +SEE ALSO +.endhelp diff --git a/pkg/obsolete/doc/orfits.hlp b/pkg/obsolete/doc/orfits.hlp new file mode 100644 index 00000000..b5993c73 --- /dev/null +++ b/pkg/obsolete/doc/orfits.hlp @@ -0,0 +1,164 @@ +.help orfits Jan90 dataio +.ih +NAME +orfits -- convert FITS data files to IRAF image files +.ih +USAGE +orfits fits_file file_list iraf_file +.ih +PARAMETERS +.ls fits_file +The FITS data source. This is either a template describing a list of disk files +or a tape file +specification of the form mt*[n], where mt indicates a mag tape device, +* represents a density, and [n] is the tape file number. +If the tape file number n is specified then only that file +is converted. If the general tape device name is given, i.e. mta, mtb800, etc, +then the files specified by the file_list parameter will be read from the tape. +.le +.ls file_list +The files to be read from a tape are specified by the file_list string. The +string can consist of any sequence of file numbers separated by +at least one of comma, or dash. +A dash specifies a range of files. For example the string + + "1,2,3-5,8-6" + +will convert the files 1 through 8. +.le +.ls iraf_file +The IRAF file which will receive the FITS data if the make_image parameter +switch is set. Iraf_file can be a template of output image names or +a root output image name. In the former case one output image name +must be specified for every input file. In the latter case iraf_file is +a root output image name to which the input file sequence number or tape +file number is appended if the number of input files > 1. For example +reading files 1 and 3 from a FITS tape with a value of iraf_file of "data" +will produce the files data0001 and data0003, whereas reading the same +two files with a value of iraf_file of "data1,data2" will produce the files +data1 and data2. +.le +.ls make_image = yes +This switch determines whether FITS image data is converted to an IRAF image +file. This switch is set to no to obtain just header information with the +long_header or short_header switches. +.le +.ls long_header = no +If this switch is set the full FITS header is printed on the standard output. +.le +.ls short_header = yes +If this switch is set only the output filename, +the title string, and the image dimensions are printed. +.le +.ls datatype +The IRAF image file may be of a different data type than the FITS image data. +The data type may be specified as s for short, u for unsigned short, +i for integer, l for long, +r for real, and d for double. The user must beware of truncation problems if an +inappropriate data type is specified. If an incorrect data_type or a +null string is given for this parameter then a default data type is used +which is the appropriate minimum size for the input pixel values. +If the bscale and bzero parameters in the FITS header are undefined or equal to +1.0 and 0.0 respectively, orfits +selects datatype s or l depending on bitpix. If bscale and bzero are set to +other than 1.0 and 0.0, orfits selects datatype r. +.le +.ls blank = 0. +The IRAF image value of a blank pixel. +.le +.ls scale = yes +If scale equals no the integers are read directly off the tape. +Otherwise ORFITS checks the values of bscale and bzero. If these numbers +are not 1. and 0. respectively, ORFITS scales the data before output. +.le +.ls oldirafname = no +If the oldirafname switch is set ORFITS will attempt to restore the image to +disk with the filename defined by the IRAFNAME parameter in the FITS header. +.le +.ls offset = 0 +Offset is an integer parameter specifying the offset to the current tape file +number. For example if offset = 100, iraf_file = "fits" and file_list = "1-3" +then the output file names will be "fits0101", "fits0102" and "fits0103" +respectively rather than "fits0001", "fits0002" and "fits0003". +.le +.ih +DESCRIPTION +FITS data is read from the specified source; either disk or +magnetic tape. The FITS header may optionally be printed on the standard +output as either a full listing or a short description. +The FITS long blocks option is supported. +At present non-standard FITS files (SIMPLE = F) and files containing +group data are skipped and a warning message is issued. +A warning message will be issued if the default user area allocated in +memory is too small +to hold all the FITS parameter cards being read in by ORFITS. +Since the default user area is 8000 +characters and a single card image is 81 characters long, the normal +user area will hold 98 complete card images. ORFITS will not permit +partial cards to be written. The user can override the default user area +length by setting the environment variable min_lenuserarea (see example +below). +.ih +EXAMPLES +1. Convert a set of FITS files on tape to a set of IRAF image files, allowing +orfits to select the output datatype. Blanks are set to zero. + +.nf + cl> orfits mtb1600 1-999 images +.fi + +2. Convert a list of FITS files on disk to a set of IRAF images. In the first +case the files specified by fits* are written to the images images0001, +images0002, etc. In the second case the fits disk files listed one per +line in the text file fitslist are written to the output images listed +one per line in the file imlist. + +.nf + cl> orfits fits* * images + + cl. orfits @fitslist * @imlist +.fi + +3. List the contents of a FITS tape on the standard output without creating +any image files. + +.nf + cl> orfits mtb1600 1-999 images ma- +.fi + +4. Convert FITS files directly to IRAF images without scaling. + +.nf + cl> orfits mtb1600 1-999 images scal- +.fi + +5. Convert the first three FITS files on tape to IRAF files setting blanks +to -1. + +.nf + cl> orfits mta 1-3 images blan=-1 +.fi + +6. Read in a FITS file with a header roughly twice the usual IRAF length +of 8000 characters. + +.nf + cl> set min_lenuserarea = 16300 + cl> orfits mta 1 images +.fi + +7. Read a FITS tape with 5 normal fits records (2880 bytes) to a tape record. +Notice that no extra parameters are needed. + +.nf + cl> orfits mta 1-3 fits +.fi + +.ih +BUGS +Blank pixels are counted and set to a user determined value, but not flagged +in the image header. +.ih +SEE ALSO +owfits, reblock, t2d +.endhelp diff --git a/pkg/obsolete/doc/owfits.hlp b/pkg/obsolete/doc/owfits.hlp new file mode 100644 index 00000000..9496192f --- /dev/null +++ b/pkg/obsolete/doc/owfits.hlp @@ -0,0 +1,205 @@ +.help owfits Jan90 dataio +.ih +NAME +owfits -- convert IRAF image files to FITS image files +.ih +USAGE +owfits iraf_files fits_files +.ih +PARAMETERS +.ls iraf_files +String parameter specifying the input file(s), e.g. "file1" or "file*". +.le +.ls fits_files +String parameter specifying the output destination. +Magnetic tape output is assumed if the first two characters of fits_files +are "mt", otherwise the output destination defaults to disk. +Tape output will begin at the file +number specified in fits_files, e.g. file 5 if fits_files = +"mtb1600[5]". Data in file 5 and succeeding files will be overwritten. +If no tape file number is specified in fits_files, the newtape parameter +is requested. Tape output will begin at BOT (beginning of tape) if +newtape = yes, otherwise at EOT (after the double EOF). +Requesting a tape write at EOT on a blank tape may cause severe problems +like tape runaway. +In the case of disk output fits_files may be either a file name template +or a root filename. In the former case there must be an output fits file +name for every image. In the latter case the image sequence number is +appended to fits_files if the number of input images > 1. +.le +.ls newtape +Boolean parameter specifying whether an output tape is blank or contains +data. Newtape is requested only if no tape file number is specified in +fits_files, e.g. fits_files = "mtb1600". +.le +.ls bscale +The FITS bscale parameter, defined as p = i * bscale + bzero, where +p and i are the physical and tape data values respectively. +The bscale parameter is only requested if the scale switch is set +and the autoscale switch is turned off. +.le +.ls bzero +The FITS bzero parameter (see bscale for a definition). +Bzero is only requested if the scale switch is set and the autoscale +switch is turned off. +.le +.ls make_image = yes +By default owfits writes the FITS image(s) to the output destination. +If the make_image switch is turned off, owfits prints the FITS headers +on the standard output and no output file is created. In this way the +output FITS headers can be examined before actually writing a FITS tape. +.le +.ls long_header = no +If this switch is set the full FITS header will be printed on the standard +output for each IRAF image converted. +.le +.ls short_header = yes +If this switch is set only a short header, listing files processed and +their dimensions will be printed on the standard output. +The long_header switch must be turned off. +.le +.ls bitpix = 0 +A bitpix of 8, 16, or 32 will produce either an unsigned byte, +twos-complement 16 bit integer, or twos-complement 32 bit integer FITS +image. If bitpix is -32 or +-64 IEEE real or double precision floating point FITS images are produced. +If bitpix is set to 0 (the default), owfits will choose one of 8, +16, 32, -32 or -64 based on the data type of the IRAF image. +For example a short integer and real image will default to bitpix 16 and +-32 respectively. +Users should be wary or overriding the default value of bitpix as loss +of precision in their data may result. In this case owfits will issue a +warning message and an estimate of the maximum loss of precision to be +expected. +.le +.ls blocking_factor = 0 +The tape blocking factor for FITS. +Wfits normally writes \fIblocking_factor\fR * 2880 byte records, +where \fIblocking_factor\fR is an integer from 1 to 10. +If \fIblocking_factor\fR = 0, owfits uses the default FITS blocking +factor specified for the device by the "fb" parameter in the +file dev$tapecap, or 1 if the "fb" parameter is not present. For +devices which support variable block sizes, e.g. 9-track tapes, exabytes +and dats, "fb" is normally set to 10. +The user may override this value by setting \fIblocking_factor\fR +>= 1 or <= 10. If the device does not support variable block sizes, e.g. +various types of cartridge drives, blocks of the size defined for the +device by the "bs" parameter in the dev$tapecap file are written +and \fIblocking_factor\fR is ignored. +.le +.ls scale = yes +If the scale switch is set, the IRAF image will be scaled before output. +Two types of scaling are available. The scaling parameters bscale and +bzero may be entered by the user (autoscale = no), or the program can +calculate the appropriate bscale and bzero factors (autoscale = yes). +If the scale switch is turned off, the IRAF image data is converted +directly to integers of the specified bitpix with possible loss of +precision. +.le +.ls autoscale = yes +If the autoscale switch is set, owfits calculates the appropriate bscale and +bzero factors +based on the IRAF image data type, and the maximum and minimum +values of the data. +.le +.ih +DESCRIPTION +IRAF data is read from disk and written to the specified destination, +either disk or magnetic tape. The FITS header may optionally be printed +on the standard output as either a full listing or a short description, +with or without creating an output image file. If a the default value +of bitpix (default = 0) is entered, owfits will select the appropriate +bitpix value based on the precision of the IRAF data. Otherwise the +user value is used with possible loss of precision. Two data scaling +options are available. In autoscale mode owfits calculates the appropriate +scaling factors based on the maximum and minimum data values in the +IRAF image and the FITS bits per pixel. Alternatively the scaling factors +can be entered directly. If no scaling is requested the IRAF data values +will be converted directly to FITS integers or floating point values +with possible loss of precision. +.ih +EXAMPLES +1. Convert a series of IRAF image files to FITS image files on a blank +magnetic tape, allowing owfits to select the appropriate bitpix +and scaling parameters. + +.nf + cl> owfits iraf_file* mtb1600[1] +.fi + +2. Convert a series of IRAF image files to FITS image files on disk, +allowing owfits to select the appropriate bitpix and scaling parameters. +In the first case the images specified by the template are written +to fits001, fits002 etc. In the second case the list of input images +specified one per line in the text file imlist are written to the +files specified one per line in the text file fitslist. + +.nf + cl> owfits iraf_file* fits + + cl> owfits @imlist @fitslist +.fi + +3. Convert an IRAF image file to a 32 bits per pixel FITS file with no +scaling and append to a tape already containing data. + +.nf + cl> owfits iraf_file mtb1600[EOT] bi=32 sc- +.fi + +4. Convert an IRAF image to a 16 bit FITS image on disk, specifying +bscale and bzero. + +.nf + cl> owfits iraf_file fits_file bi=16 au- bs=4.0 bz=0.0 +.fi + +5. Print the FITS headers on the standard output. + +.nf + cl> owfits iraf_file* ma- +.fi + +6. Create a disk file called headers containing the FITS headers for a set +of IRAF image files. + +.nf + cl> owfits iraf_file* ma- > headers +.fi + +7. Write a FITS tape with 14400 bytes per record (5 2880 FITS records per +tape block) on a 9-track tape. + +.nf + cl> owfits images* mtb[1] block=5 +.fi + +8. Write a FITS Exabyte tape with a blocking factor of 1 (1 2880 FITS record +per block). Note that owfits will normally by default write a 28000 ( +10 2880 FITS logical records per block) byte record. + +.nf + cl> owfits images* mtb[1] block=1 +.fi +.ih +BUGS +OWFITS does not attempt to recover from write errors. When an error is +detected, OWFITS issues an error message and attempts to write a double +EOF at the end of the last good record. In this case the last file on +the tape will be a partial file. IF OWFITS is not successful in writing +the double EOF, the message "Cannot close magtape file (name)" will be +issued. Problems occur as some drives permit the double EOF to be +written after the physical end of tape and some do not. Similarly +some drives can read a double EOF after end of tape and some cannot. Depending +on operating system and device driver, an attempt to read or write past +end of tape may or may not be distinguishable from a normal write error. + +Blank pixel values are not correctly handled. + +Attempting to write at EOT on a blank tape will at best result in numerous +error messages being issued and at worst result in tape runaway depending +on the driver. +.ih +SEE ALSO +orfits, reblock +.endhelp diff --git a/pkg/obsolete/doc/radplt.hlp b/pkg/obsolete/doc/radplt.hlp new file mode 100644 index 00000000..eb98d038 --- /dev/null +++ b/pkg/obsolete/doc/radplt.hlp @@ -0,0 +1,57 @@ +.help radplt Dec85 obsolete +.ih +NAME +radplt -- plot a radial profile of a stellar image +.ih +USAGE +radplt input x_init y_init +.ih +PARAMETERS +.ls input +the list of images which contain the star whose profile is to be plotted +.le +.ls x_init +the approximate column coordinate as a starting point for the centering +.le +.ls y_init +the approximate line (row) coordinate as a starting point for the centering +.le +.ls cboxsize = 5 +the size of the extraction box to be used during the centering process +.le +.ls rboxsize = 21 +the size of the extraction box to be used for the radial profile. The +profile will extend to sqrt(2) * rboxsize / 2. This is the length +of the diagonal from the box center to a corner, and corresponds to about +14 pixels for the default value. +.le +.ih +DESCRIPTION +Given the approximate coordinates of the center of a star, (x_init, y_init), +RADPLT will compute a more accurate center using the algorithms described in +the Kitt Peak publication "Stellar Magnitudes from Digital Images" under +the Mountain Photometry Code section and then plot the intensity values +in the profile extraction box as a function of distance from the center. +This is effectively a radial profile. + +The values for both box sizes should be odd. +.ih +EXAMPLES +The following example plots the profile of a star near (123, 234): +.sp 1 +.nj +.nf +cl> radplt m92red 123 234 +.fi +.ju +.ih +BUGS +The routine will probably fail if the desired star is within 2 or 3 pixels +of the image boundary. +.ih +USE INSTEAD +plot.pradprof +.ih +SEE ALSO +imcntr +.endhelp diff --git a/pkg/obsolete/fits/README b/pkg/obsolete/fits/README new file mode 100644 index 00000000..b9c10c7b --- /dev/null +++ b/pkg/obsolete/fits/README @@ -0,0 +1 @@ +The IRAF code for the FITS I/O package. diff --git a/pkg/obsolete/fits/fits_cards.x b/pkg/obsolete/fits/fits_cards.x new file mode 100644 index 00000000..fe4829c9 --- /dev/null +++ b/pkg/obsolete/fits/fits_cards.x @@ -0,0 +1,250 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "wfits.h" + +# WFT_STANDARD_CARD -- Procedure for fetching the minimum header +# parameters required by fits. The end card is encoded separately. + +int procedure wft_standard_card (cardno, im, fits, axisno, card) + +int cardno # number of FITS standard card +pointer im # pointer to the IRAF image +pointer fits # pointer to the FITS structure +int axisno # axis number +char card[ARB] # FITS card image + +char keyword[LEN_KEYWORD] +errchk wft_encodeb, wft_encodei, wft_encodel, wft_encode_axis +include "wfits.com" + +begin + # Get mandatory keywords. + switch (cardno) { + case FIRST_CARD: + call wft_encodeb ("SIMPLE", YES, card, "FITS STANDARD") + case SECOND_CARD: + call wft_encodei ("BITPIX", FITS_BITPIX(fits), card, + "FITS BITS/PIXEL") + case THIRD_CARD: + call wft_encodei ("NAXIS", NAXIS(im), card, "NUMBER OF AXES") + default: + call wft_encode_axis ("NAXIS", keyword, axisno) + call wft_encodel (keyword, NAXISN(im, axisno), card, "") + axisno = axisno + 1 + } + + return (YES) +end + + +# WFT_OPTION_CARD -- Procedure for fetching optional FITS header parameters. +# At present these are bscale, bzero, bunit, blank, object, origin, date, +# irafmax, irafmin, iraf type and iraf bits per pixel. Blank is only encoded +# if there are a nonzero number of blanks in the IRAF image. Bunit and object +# are only encoded if the appropriate IRAF strings are defined. Bzero, bscale, +# irafmax, irafmin, iraf type and iraf bits per pixel are only encoded if +# there is a pixel file. + +int procedure wft_option_card (im, fits, optiono, card) + +pointer im # pointer to the IRAF image +pointer fits # pointer to FITS structure +int optiono # number of the option card +char card[ARB] # FITS card image + +char datestr[LEN_STRING] +int len_object, stat +int strlen() +errchk wft_encoded, wft_encodec, wft_encode_blank, wft_encoder, wft_encodei +errchk wft_encode_date + +begin + stat = YES + + # get optional keywords + switch (optiono) { + case KEY_BSCALE: + if ((NAXIS(im) <= 0) || (FITS_BITPIX(fits) < 0)) + stat = NO + else { + call wft_encoded ("BSCALE", BSCALE(fits), card, + "REAL = TAPE*BSCALE + BZERO", NDEC_DOUBLE) + } + case KEY_BZERO: + if ((NAXIS(im) <= 0) || (FITS_BITPIX(fits) < 0)) + stat = NO + else + call wft_encoded ("BZERO", BZERO(fits), card, "", NDEC_DOUBLE) + case KEY_BUNIT: + stat = NO + case KEY_BLANK: + stat = NO + #if (NBPIX(im) == 0) + #stat = NO + #else + #call wft_encode_blank ("BLANK", BLANK_STRING(fits), card, + #"TAPE VALUE OF BLANK PIXEL") + case KEY_OBJECT: + if (OBJECT(im) == EOS) + stat = NO + else { + len_object = max (min (LEN_OBJECT, strlen (OBJECT(im))), + LEN_STRING) + call wft_encodec ("OBJECT", OBJECT(im), len_object, card, "") + } + case KEY_ORIGIN: + call wft_encodec ("ORIGIN", "KPNO-IRAF", LEN_ORIGIN, card, "") + case KEY_DATE: + call wft_encode_date (datestr, LEN_STRING) + call wft_encodec ("DATE", datestr, LEN_STRING, card, "") + case KEY_IRAFNAME: + len_object = max (min (LEN_OBJECT, strlen (IRAFNAME(fits))), + LEN_STRING) + call wft_encodec ("IRAFNAME", IRAFNAME(fits), len_object, card, + "NAME OF IRAF IMAGE FILE") + case KEY_IRAFMAX: + if (NAXIS(im) <= 0) + stat = NO + else + call wft_encoder ("IRAF-MAX", IRAFMAX(fits), card, "DATA MAX", + NDEC_REAL) + case KEY_IRAFMIN: + if (NAXIS(im) <= 0) + stat = NO + else + call wft_encoder ("IRAF-MIN", IRAFMIN(fits), card, "DATA MIN", + NDEC_REAL) + case KEY_IRAFBP: + if (NAXIS(im) <= 0) + stat = NO + else + call wft_encodei ("IRAF-BPX", DATA_BITPIX(fits), card, + "DATA BITS/PIXEL") + case KEY_IRAFTYPE: + if (NAXIS(im) <= 0) + stat = NO + else + call wft_encodec ("IRAFTYPE", TYPE_STRING(fits), LEN_STRING, + card, "PIXEL TYPE") + default: + stat = NO + } + + optiono = optiono + 1 + + return (stat) +end + + +# WFT_HISTORY_CARD -- Procedure to fetch a single history line, trim newlines +# and pad with blanks to size LEN_CARD in order to create a FITS HISTORY card. + +int procedure wft_history_card (im, hp, card) + +pointer im # pointer to the IRAF image +int hp # pointer to first character to extract from string +char card[ARB] # FITS card image + +char cval +char chfetch() + +begin + if (chfetch (HISTORY(im), hp, cval) == EOS) + return (NO) + else { + hp = hp - 1 + call strcpy ("HISTORY ", card, LEN_KEYWORD) + call wft_fits_card (HISTORY(im), hp, card, COL_VALUE - 2, LEN_CARD, + '\n') + return (YES) + } +end + + +# WFT_UNKNOWN_CARD -- Procedure to fetch a single unknown +# "line", trim newlines and pad blanks to size LEN_CARD in order to +# create an unknown keyword card. At present user area information is +# assumed to be in the form of FITS card images, less then or equal to +# 80 characters and delimited by a newline. + +int procedure wft_unknown_card (im, up, card) + +pointer im # pointer to the IRAF image +int up # pointer to next character in the unknown string +char card[ARB] # FITS card image + +char cval +int stat, axis, index +char chfetch() +int strmatch(), ctoi() + +begin + if (chfetch (UNKNOWN(im), up, cval) == EOS) + return (NO) + else { + up = up - 1 + stat = NO + while (stat == NO) { + call wft_fits_card (UNKNOWN(im), up, card, 1, LEN_CARD, '\n') + if (card[1] == EOS) + break + if (strmatch (card, "^GROUPS ") != 0) { + stat = NO + } else if (strmatch (card, "^SIMPLE ") != 0) { + stat = NO + } else if (strmatch (card, "^BITPIX ") != 0) { + stat = NO + } else if (strmatch (card, "^NAXIS ") != 0) { + stat = NO + } else if (strmatch (card, "^NAXIS") != 0) { + index = LEN_NAXIS_KYWRD + 1 + if (ctoi (card, index, axis) > 0) + stat = NO + else + stat = YES + } else if (strmatch (card, "^GCOUNT ") != 0) { + stat = NO + } else if (strmatch (card, "^PCOUNT ") != 0) { + stat = NO + } else if (strmatch (card, "^PSIZE ") != 0) { + stat = NO + } else if (strmatch (card, "^BSCALE ") != 0) { + stat = NO + } else if (strmatch (card, "^BZERO ") != 0) { + stat = NO + } else if (strmatch (card, "^BLANK ") != 0) { + stat = NO + } else if (strmatch (card, "^IRAF-MAX") != 0) { + stat = NO + } else if (strmatch (card, "^IRAF-MIN") != 0) { + stat = NO + } else if (strmatch (card, "^IRAFTYPE") != 0) { + stat = NO + } else if (strmatch (card, "^IRAF-B/P") != 0) { + stat = NO + } else if (strmatch (card, "^IRAF-BPX") != 0) { + stat = NO + } else if (strmatch (card, "^END ") != 0) { + stat = NO + } else + stat = YES + } + + return (stat) + } +end + + +# WFT_LAST_CARD -- Procedure to encode the FITS end card. + +int procedure wft_last_card (card) + +char card[ARB] # FITS card image + +begin + call sprintf (card, LEN_CARD, "%-8.8s %70w") + call pargstr ("END") + + return (YES) +end diff --git a/pkg/obsolete/fits/fits_params.x b/pkg/obsolete/fits/fits_params.x new file mode 100644 index 00000000..e3bf04ba --- /dev/null +++ b/pkg/obsolete/fits/fits_params.x @@ -0,0 +1,234 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <time.h> +include "wfits.h" + +# WFT_ENCODEB -- Procedure to encode a boolean parameter into a FITS card. + +procedure wft_encodeb (keyword, param, card, comment) + +char keyword[ARB] # FITS keyword +int param # integer parameter equal to YES/NO +char card[ARB] # FITS card image +char comment[ARB] # FITS comment string + +char truth + +begin + if (param == YES) + truth = 'T' + else + truth = 'F' + + call sprintf (card, LEN_CARD, "%-8.8s= %20c / %-45.45s") + call pargstr (keyword) + call pargc (truth) + call pargstr (comment) +end + + +# WFT_ENCODEI -- Procedure to encode an integer parameter into a FITS card. + +procedure wft_encodei (keyword, param, card, comment) + +char keyword[ARB] # FITS keyword +int param # integer parameter +char card[ARB] # FITS card image +char comment[ARB] # FITS comment string + +begin + call sprintf (card, LEN_CARD, "%-8.8s= %20d / %-45.45s") + call pargstr (keyword) + call pargi (param) + call pargstr (comment) +end + + +# WFT_ENCODEL -- Procedure to encode a long parameter into a FITS card. + +procedure wft_encodel (keyword, param, card, comment) + +char keyword[ARB] # FITS keyword +long param # long integer parameter +char card[ARB] # FITS card image +char comment[ARB] # FITS comment string + +begin + call sprintf (card, LEN_CARD, "%-8.8s= %20d / %-45.45s") + call pargstr (keyword) + call pargl (param) + call pargstr (comment) +end + + +# WFT_ENCODER -- Procedure to encode a real parameter into a FITS card. + +procedure wft_encoder (keyword, param, card, comment, precision) + +char keyword[ARB] # FITS keyword +real param # real parameter +char card[ARB] # FITS card image +char comment[ARB] # FITS comment card +int precision # precision of real + +begin + call sprintf (card, LEN_CARD, "%-8.8s= %20.*e / %-45.45s") + call pargstr (keyword) + call pargi (precision) + call pargr (param) + call pargstr (comment) +end + + +# WFT_ENCODED -- Procedure to encode a double parameter into a FITS card. + +procedure wft_encoded (keyword, param, card, comment, precision) + +char keyword[ARB] # FITS keyword +double param # double parameter +char card[ARB] # FITS card image +char comment[ARB] # FITS comment string +int precision # FITS precision + +begin + call sprintf (card, LEN_CARD, "%-8.8s= %20.*e / %-45.45s") + call pargstr (keyword) + call pargi (precision) + call pargd (param) + call pargstr (comment) +end + + +# WFT_ENCODE_AXIS -- Procedure to add the axis number to axis dependent +# keywords. + +procedure wft_encode_axis (root, keyword, axisno) + +char root[ARB] # FITS root keyword +char keyword[ARB] # FITS keyword +int axisno # FITS axis number + +begin + call strcpy (root, keyword, LEN_KEYWORD) + call sprintf (keyword, LEN_KEYWORD, "%-5.5s%-3.3s") + call pargstr (root) + call pargi (axisno) +end + + +# WFT_ENCODEC -- Procedure to encode an IRAF string parameter into a FITS card. + +procedure wft_encodec (keyword, param, maxch, card, comment) + +char keyword[ARB] # FITS keyword +char param[ARB] # FITS string parameter +int maxch # maximum number of characters in string parameter +char card[ARB] # FITS card image +char comment[ARB] # comment string + +char strparam[LEN_ALIGN+2] +int maxchar, nblanks + +begin + maxchar = min (maxch, LEN_OBJECT) + if (maxchar <= LEN_ALIGN - 1) { + strparam[1] = '\'' + call sprintf (strparam[2], maxchar, "%*.*s") + call pargi (-maxchar) + call pargi (maxchar) + call pargstr (param) + strparam[maxchar+2] = '\'' + strparam[maxchar+3] = EOS + call sprintf (card, LEN_CARD, "%-8.8s= %-20.20s / %-45.45s") + call pargstr (keyword) + call pargstr (strparam) + call pargstr (comment) + } else { + nblanks = LEN_OBJECT - maxchar + call sprintf (card, LEN_CARD, "%-8.8s= '%*.*s' / %*.*s") + call pargstr (keyword) + call pargi (-maxchar) + call pargi (maxchar) + call pargstr (param) + call pargi (-nblanks) + call pargi (nblanks) + call pargstr (comment) + } +end + + +# WFT_ENCODE_BLANK -- Procedure to encode the FITS blank parameter. Necessary +# because the 32 bit blank value equals INDEFL. + +procedure wft_encode_blank (keyword, blank_str, card, comment) + +char keyword[ARB] # FITS keyword +char blank_str[ARB] # string containing values of FITS blank integer +char card[ARB] # FITS card image +char comment[ARB] # FITS comment string + +begin + call sprintf (card, LEN_CARD, "%-8.8s= %20.20s / %-45.45s") + call pargstr (keyword) + call pargstr (blank_str) + call pargstr (comment) +end + + +# WFT_ENCODE_DATE -- Procedure to encode the date in the form dd-mm-yy. + +procedure wft_encode_date (datestr, szdate) + +char datestr[ARB] # string containing the date +int szdate # number of chars in the date string + +long ctime +int time[LEN_TMSTRUCT] +long clktime() + +begin + ctime = clktime (long (0)) + call brktime (ctime, time) + + call sprintf (datestr, szdate, "%02s-%02s-%02s") + call pargi (TM_MDAY(time)) + call pargi (TM_MONTH(time)) + call pargi (mod (TM_YEAR(time), CENTURY)) +end + + +# WFT_FITS_CARD -- Procedure to fetch a single line from a string parameter +# padding it to a maximum of maxcols characters and trimmimg the delim +# character. + +procedure wft_fits_card (instr, ip, card, col_out, maxcols, delim) + +char instr[ARB] # input string +int ip # input string pointer, updated at each call +char card[ARB] # FITS card image +int col_out # pointer to column in card +int maxcols # maximum columns in card +int delim # 1 character string delimiter + +int op + +begin + op = col_out + + # Copy string + while (op <= maxcols && instr[ip] != EOS && instr[ip] != delim) { + card[op] = instr[ip] + ip = ip + 1 + op = op + 1 + } + + # Fill remainder of card with blanks + while (op <= maxcols ) { + card[op] = ' ' + op = op + 1 + } + + if (instr[ip] == delim) + ip = ip + 1 + +end diff --git a/pkg/obsolete/fits/fits_read.x b/pkg/obsolete/fits/fits_read.x new file mode 100644 index 00000000..bcbdb745 --- /dev/null +++ b/pkg/obsolete/fits/fits_read.x @@ -0,0 +1,173 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> +include <fset.h> +include "rfits.h" + +# RFT_READ_FITZ -- Convert a FITS file. An EOT is signalled by returning EOF. + +int procedure rft_read_fitz (fitsfile, iraffile) + +char fitsfile[ARB] # FITS file name +char iraffile[ARB] # IRAF file name + +int fits_fd, stat, min_lenuserarea, ip +pointer im, sp, fits, envstr +int rft_read_header(), mtopen(), immap(), strlen(), envfind(), ctoi() +errchk smark, sfree, salloc, rft_read_header, rft_read_image, rft_find_eof() +errchk rft_scan_file, mtopen, immap, imdelete, close, imunmap + +include "rfits.com" + +begin + # Open input FITS data. + fits_fd = mtopen (fitsfile, READ_ONLY, 0) + + # Allocate memory for program data structure. + call smark (sp) + call salloc (fits, LEN_FITS, TY_STRUCT) + call salloc (envstr, SZ_FNAME, TY_CHAR) + + # Set up for printing a long or a short header. + if (long_header == YES || short_header == YES) { + if (make_image == YES) { + call printf ("File: %s ") + call pargstr (iraffile) + } else { + call printf ("File: %s ") + call pargstr (fitsfile) + } + if (long_header == YES) + call printf ("\n") + } + call flush (STDOUT) + + # Create the IRAF image header. If only a header listing is desired + # then map the scratch image onto DEV$NULL (faster than a real file). + + if (make_image == NO) + call strcpy ("dev$null", iraffile, SZ_FNAME) + if (envfind ("min_lenuserarea", Memc[envstr], SZ_FNAME) > 0) { + ip = 1 + if (ctoi (Memc[envstr], ip, min_lenuserarea) <= 0) + min_lenuserarea = LEN_USERAREA + else + min_lenuserarea = max (LEN_USERAREA, min_lenuserarea) + } else + min_lenuserarea = LEN_USERAREA + im = immap (iraffile, NEW_IMAGE, min_lenuserarea) + + # Read header. EOT is signalled by an EOF status from fits_read_header. + # Create an IRAF image if desired. + + iferr { + IRAFNAME(fits) = EOS + stat = rft_read_header (fits_fd, fits, im) + if (stat == EOF) + call printf ("End of data\n") + else { + if (make_image == YES) { + call rft_read_image (fits_fd, fits, im) + if (fe > 0.0) + call rft_find_eof (fits_fd) + } else if (fe > 0.0) + call rft_scan_file (fits_fd, fits, im, fe) + } + } then { + call flush (STDOUT) + call erract (EA_WARN) + } + + # Close files and clean up. + call imunmap (im) + + # Optionally restore the old IRAF name. + if (stat == EOF || make_image == NO) { + call imdelete (iraffile) + } else if (old_name == YES && strlen (IRAFNAME(fits)) != 0) { + iferr { + call imgimage (IRAFNAME(fits), IRAFNAME(fits), SZ_FNAME) + call imrename (iraffile, IRAFNAME(fits)) + } then { + call printf (" Cannot rename image %s to %s\n") + call pargstr (iraffile) + call pargstr (IRAFNAME(fits)) + call flush (STDOUT) + call erract (EA_WARN) + } else { + call printf (" File: %s restored to IRAF File: %s\n") + call pargstr (iraffile) + call pargstr (IRAFNAME(fits)) + } + } + + if (long_header == YES) + call printf ("\n") + + call close (fits_fd) + call sfree (sp) + + return (stat) +end + + +# RFT_FIND_EOF -- Read the FITS data file until EOF is reached. + +procedure rft_find_eof (fd) + +int fd # the FITS file descriptor + +int szbuf +pointer sp, buf +int fstati(), read() +errchk read + +begin + # Scan through the file. + szbuf = fstati (fd, F_BUFSIZE) + call smark (sp) + call salloc (buf, szbuf, TY_CHAR) + while (read (fd, Memc[buf], szbuf) != EOF) + ; + call sfree (sp) +end + + +# RFT_SCAN_FILE -- Determine whether it is more efficient to read the +# entire file or to skip forward to the next file if the parameter +# make_image was set to no. + +procedure rft_scan_file (fd, fits, im, fe) + +int fd # the FITS file descriptor +pointer fits # pointer to the FITS descriptor +pointer im # pointer to the output image +real fe # maximum file size in Kb for scan mode + +int i, szbuf +pointer sp, buf +real file_size +int fstati(), read() +errchk read + +begin + # Compute the file size in Kb and return if it is bigger than fe. + file_size = 1.0 + do i = 1, IM_NDIM(im) + file_size = file_size * IM_LEN(im,i) + if (IM_NDIM(im) <= 0) + file_size = 0.0 + else + file_size = file_size * abs (BITPIX(fits)) / FITS_BYTE / 1.0e3 + if (file_size >= fe) + return + + # Scan through the file. + szbuf = fstati (fd, F_BUFSIZE) + call smark (sp) + call salloc (buf, szbuf, TY_CHAR) + while (read (fd, Memc[buf], szbuf) != EOF) + ; + call sfree (sp) +end diff --git a/pkg/obsolete/fits/fits_rheader.x b/pkg/obsolete/fits/fits_rheader.x new file mode 100644 index 00000000..8efb5562 --- /dev/null +++ b/pkg/obsolete/fits/fits_rheader.x @@ -0,0 +1,575 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctype.h> +include <imhdr.h> +include <imio.h> +include <mach.h> +include "rfits.h" + +define NEPSILON 10.0d0 # number of machine epsilon + +# RFT_READ_HEADER -- Read a FITS header. +# If BSCALE and BZERO are different from 1.0 and 0.0 scale is set to true +# otherwise scale is false. +# EOT is detected by an EOF on the first read and EOF is returned to the calling +# routine. Any error is passed to the calling routine. + +int procedure rft_read_header (fits_fd, fits, im) + +int fits_fd # FITS file descriptor +pointer fits # FITS data structure +pointer im # IRAF image descriptor + +int i, stat, nread, max_lenuser, fd_usr, ndiscard +char card[LEN_CARD+1] +int rft_decode_card(), rft_init_read_pixels(), rft_read_pixels(), strmatch() +int stropen() +errchk rft_decode_card, rft_init_read_pixels, rft_read_pixels +errchk stropen, close + +include "rfits.com" + +begin + # Initialization. + SIMPLE(fits) = NO + BITPIX(fits) = INDEFI + NAXIS(im) = INDEFI + do i = 1, IM_MAXDIM + IM_LEN(im,i) = INDEFL + SCALE(fits) = NO + FITS_BSCALE(fits) = 1.0d0 + FITS_BZERO(fits) = 0.0d0 + BLANKS(fits) = NO + BLANK_VALUE(fits) = INDEFL + NRECORDS(fits) = 0 + ndiscard = 0 + max_lenuser = (LEN_IMDES + IM_LENHDRMEM(im) - IMU) * SZ_STRUCT - 1 + + # The FITS header is character data in FITS_BYTE form. Open the + # header for reading. Open the user area which is a character + # string as a file. + + i = rft_init_read_pixels (len_record, FITS_BYTE, LSBF, TY_CHAR) + fd_usr = stropen (UNKNOWN(im), max_lenuser, NEW_FILE) + + # Loop until the END card is encountered. + nread = 0 + repeat { + + # Read the card. + i = rft_read_pixels (fits_fd, card, LEN_CARD, NRECORDS(fits), 1) + card[LEN_CARD + 1] = '\n' + card[LEN_CARD + 2] = EOS + + # Decode the card images. + if ((i == EOF) && (nread == 0)) { + return (EOF) + } else if ((nread == 0) && strmatch (card, "^SIMPLE ") == 0) { + call flush (STDOUT) + call error (30, + "RFT_READ_HEADER: Not a FITS file (no SIMPLE keyword)") + } else if (i != LEN_CARD) { + call error (2, "RFT_READ_HEADER: Error reading FITS header") + } else + nread = nread + 1 + + # Remove contaminating control characters and replace with blanks. + call rft_control_to_blank (card, card, LEN_CARD) + + # Print FITS card images if long_header option specified. + if (long_header == YES) { + call printf ("%-80.80s\n") + call pargstr (card) + } + + # Stat = YES if FITS END card is encountered. + stat = rft_decode_card (fits, im, fd_usr, card, ndiscard) + + } until (stat == YES) + + # Print optional short header. + if (short_header == YES && long_header == NO) { + if (make_image == NO && old_name == YES) { + call printf ("(%s) %-20.20s ") + call pargstr (IRAFNAME(fits)) + call pargstr (OBJECT(im)) + } else { + call printf ("%-20.20s ") + call pargstr (OBJECT(im)) + } + do i = 1, NAXIS(im) { + if (i == 1) { + call printf ("Size = %d") + call pargl (NAXISN(im,i)) + } else { + call printf (" x %d") + call pargl (NAXISN(im,i)) + } + } + call printf ("\n") + } + + # Let the user know if there is not enough space in the user area. + if (ndiscard > 0) { + call printf ( + "Warning: User area too small %d card images discarded\n") + call pargi (ndiscard) + call rft_last_user (UNKNOWN(im), max_lenuser) + } + + call close (fd_usr) + return (OK) +end + + +# RFT_CONTROL_TO_BLANK -- Replace an ACSII control characters in the +# FITS card image with blanks. + +procedure rft_control_to_blank (incard, outcard, len_card) + +char incard[ARB] # the input FITS card image +char outcard[ARB] # the output FITS card image +int len_card # the length of the FITS card image + +int i + +begin + for (i = 1; i <= len_card; i = i + 1) { + if (IS_PRINT(incard[i])) + outcard[i] = incard[i] + else + outcard[i] = ' ' + } +end + + +# RFT_DECODE_CARD -- Decode a FITS card and return YES when the END +# card is encountered. The keywords understood are given in rfits.h. + +int procedure rft_decode_card (fits, im, fd_usr, card, ndiscard) + +pointer fits # FITS data structure +pointer im # IRAF image descriptor +int fd_usr # file descriptor of user area +char card[ARB] # FITS card +int ndiscard # Number of cards for which no space available + +char cval, str[LEN_CARD] +double dval +int nchar, ival, i, j, k, len +pointer sp, comment + +bool rft_equald() +int strmatch(), ctoi(), ctol(), ctod(), cctoc(), rft_hms() +errchk putline + +include "rfits.com" + +begin + call smark (sp) + call salloc (comment, SZ_LINE, TY_CHAR) + + i = COL_VALUE + if (strmatch (card, "^END ") != 0) { + call sfree (sp) + return(YES) + } else if (strmatch (card, "^SIMPLE ") != 0) { + if (SIMPLE(fits) == YES) + call printf ("Warning: Duplicate SIMPLE keyword ignored\n") + else { + nchar = cctoc (card, i, cval) + if (cval != 'T') + call error (13, "RFT_DECODE_CARD: Non-standard FITS format") + SIMPLE(fits) = YES + } + } else if (strmatch (card, "^BITPIX ") != 0) { + if (! IS_INDEFI(BITPIX(fits))) + call printf ("Warning: Duplicate BITPIX keyword ignored\n") + else + nchar = ctoi (card, i, BITPIX(fits)) + } else if (strmatch (card, "^BLANK ") != 0) { + BLANKS(fits) = YES + nchar = ctol (card, i, BLANK_VALUE(fits)) + } else if (strmatch (card, "^NAXIS ") != 0) { + if (! IS_INDEFI(NAXIS(im))) + call printf ("Warning: Duplicate NAXIS keyword ignored\n") + else + nchar = ctoi (card, i, NAXIS(im)) + if (NAXIS(im) > IM_MAXDIM) + call error (5, "RFT_DECODE_CARD: FITS NAXIS too large") + } else if (strmatch (card, "^NAXIS") != 0) { + k = strmatch (card, "^NAXIS") + nchar = ctoi (card, k, j) + if (! IS_INDEFL(NAXISN(im,j))) { + call printf ("Warning: Duplicate NAXIS%d keyword ignored\n") + call pargi (j) + } else + nchar = ctol (card, i, NAXISN(im, j)) + } else if (strmatch (card, "^GROUPS ") != 0) { + nchar = cctoc (card, i, cval) + if (cval == 'T') { + NAXIS(im) = 0 + call error (6, "RFT_DECODE_CARD: Group data not implemented") + } + } else if (strmatch (card, "^TABLES ") != 0) { + nchar = ctoi (card, i, ival) + if (ival > 0) + call printf ("Warning: FITS special records not decoded\n") + } else if (strmatch (card, "^BSCALE ") != 0) { + nchar = ctod (card, i, dval) + if (nchar > 0) + FITS_BSCALE(fits) = dval + else + call printf ("Warning: Error decoding BSCALE, BSCALE=1.0\n") + if (! rft_equald (dval, 1.0d0) && (scale == YES)) + SCALE(fits) = YES + } else if (strmatch (card, "^BZERO ") != 0) { + nchar = ctod (card, i, dval) + if (nchar > 0) + FITS_BZERO(fits) = dval + else + call printf ("Warning: Error decoding BZERO, BZERO=0.0\n") + if (! rft_equald (dval, 0.0d0) && (scale == YES)) + SCALE(fits) = YES + } else if (strmatch (card, "^OBJECT ") != 0) { + call rft_get_fits_string (card, OBJECT(im), SZ_OBJECT) + } else if (strmatch (card, "^IRAFNAME") != 0) { + call rft_get_fits_string (card, IRAFNAME(fits), SZ_FNAME) + } else if (strmatch (card, "^ORIGIN ") != 0) { + call rft_trim_card (card, card, LEN_CARD) + call strcat (card[i], HISTORY(im), SZ_HISTORY) + } else if (strmatch (card, "^DATE ") != 0) { + call rft_trim_card (card, card, LEN_CARD) + call strcat (card[i], HISTORY(im), SZ_HISTORY) + #} else if (strmatch (card, "^HISTORY ") != 0) { + #call rft_trim_card (card, card, LEN_CARD) + #call strcat (card[i - 2], HISTORY(im), SZ_HISTORY) + } else if (strmatch (card, "^UT ") != 0) { + len = rft_hms (card, str, Memc[comment], LEN_CARD) + if (len > 0) { + call wft_encodec ("UT", str, len, card, Memc[comment]) + card[LEN_CARD+1] = '\n' + card[LEN_CARD+2] = EOS + } + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } else if (strmatch (card, "^ZD ") != 0) { + len = rft_hms (card, str, Memc[comment], LEN_CARD) + if (len > 0) { + call wft_encodec ("ZD", str, len, card, Memc[comment]) + card[LEN_CARD+1] = '\n' + card[LEN_CARD+2] = EOS + } + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } else if (strmatch (card, "^ST ") != 0) { + len = rft_hms (card, str, Memc[comment], LEN_CARD) + if (len > 0) { + call wft_encodec ("ST", str, len, card, Memc[comment]) + card[LEN_CARD+1] = '\n' + card[LEN_CARD+2] = EOS + } + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } else if (strmatch (card, "^RA ") != 0) { + len = rft_hms (card, str, Memc[comment], LEN_CARD) + if (len > 0) { + call wft_encodec ("RA", str, len, card, Memc[comment]) + card[LEN_CARD+1] = '\n' + card[LEN_CARD+2] = EOS + } + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } else if (strmatch (card, "^DEC ") != 0) { + len = rft_hms (card, str, Memc[comment], LEN_CARD) + if (len > 0) { + call wft_encodec ("DEC", str, len, card, Memc[comment]) + card[LEN_CARD+1] = '\n' + card[LEN_CARD+2] = EOS + } + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } else { + if (ndiscard > 1) + ndiscard = ndiscard + 1 + else { + iferr (call putline (fd_usr, card)) + ndiscard = ndiscard + 1 + } + } + + call sfree (sp) + + return (NO) + +end + + +# RFT_HMS -- Procedure to decode a FITS HMS card from the mountain. + +int procedure rft_hms (card, str, comment, maxch) + +char card[ARB] # FITS card +char str[ARB] # string +char comment[ARB] # comment string +int maxch # maximum number of characters + +char colon, minus +int ip, nchar, fst, lst, deg, min +real sec +int stridx(), strldx(), strlen(), ctoi(), ctor() + +begin + # Return if not a FITS string parameter. + if (card[COL_VALUE] != '\'') + return (0) + + # Set up key characters. + colon = ':' + minus = '-' + + # Get the FITS string. + call rft_get_fits_string (card, str, maxch) + + # Get the comment string. + call rft_get_comment (card, comment, maxch) + + # Test for blank string and for 2 colon delimiters. + if (str[1] == EOS) + return (0) + fst = stridx (colon, str) + if (fst == 0) + return (0) + lst = strldx (colon, str) + if (lst == 0) + return (0) + if (fst == lst) + return (0) + + # Decode the degrees field. + ip = 1 + while (IS_WHITE(str[ip])) + ip = ip + 1 + if (str[ip] == '+' || str[ip] == '-') + ip = ip + 1 + nchar = ctoi (str, ip, deg) + if (nchar == 0) + deg = 0 + + # Decode the minutes field. + ip = fst + 1 + while (IS_WHITE(str[ip])) + ip = ip + 1 + if (str[ip] == '+' || str[ip] == '-') + ip = ip + 1 + nchar = ctoi (str, ip, min) + if (nchar == 0) + min = 0 + + # Decode the seconds field. + ip = lst + 1 + while (IS_WHITE(str[ip])) + ip = ip + 1 + if (str[ip] == '+' || str[ip] == '-') + ip = ip + 1 + nchar = ctor (str, ip, sec) + if (nchar == 0) + sec = 0.0 + + # Reformat the HMS card. + if (stridx (minus, str) > 0 || deg < 0 || min < 0 || sec < 0.0) { + call sprintf (str, maxch, "%c%d:%02d:%05.2f") + call pargc (minus) + call pargi (abs (deg)) + call pargi (abs (min)) + call pargr (abs (sec)) + } else { + call sprintf (str, maxch, "%2d:%02d:%05.2f") + call pargi (deg) + call pargi (abs (min)) + call pargr (abs (sec)) + } + + return (strlen (str)) +end + + +# RFT_GET_COMMENT -- Extract the comment field from a FITS card. + +procedure rft_get_comment (card, comment, maxch) + +char card[ARB] # FITS card +char comment[ARB] # comment string +int maxch # maximum number of characters + +int istart, j + +begin + istart = 0 + for (j = LEN_CARD; (j >= 1) && (card[j] != '\''); j = j - 1) { + if (card[j] == '/') { + for (istart = j + 1; IS_WHITE(card[istart]) && istart <= + LEN_CARD; istart = istart + 1) + ; + break + } + } + + if (istart == 0) + comment[1] = EOS + else + call strcpy (card[istart], comment, LEN_CARD - istart + 1 ) +end + + +# RFT_GET_FITS_STRING -- Extract a string from a FITS card and trim trailing +# blanks. The EOS is marked by either ', /, or the end of the card. +# There may be an optional opening ' (FITS standard). + +procedure rft_get_fits_string (card, str, maxchar) + +char card[ARB] # FITS card +char str[ARB] # FITS string +int maxchar # maximum number of characters + +int j, istart, nchar + +begin + # Check for opening quote + for (istart = COL_VALUE; istart <= LEN_CARD && card[istart] != '\''; + istart = istart + 1) + ; + istart = istart + 1 + + # Check for closing quote. + for (j = istart; (j<LEN_CARD)&&(card[j]!='\''); j = j + 1) + ; + for (j = j - 1; (j >= istart) && (card[j] == ' '); j = j - 1) + ; + nchar = min (maxchar, j - istart + 1) + + # Copy the string. + if (nchar <= 0) + str[1] = EOS + else + call strcpy (card[istart], str, nchar) +end + + +# RFT_EQUALD -- Procedure to compare two double precision numbers for equality +# to within the machine precision for doubles. + +bool procedure rft_equald (x, y) + +double x, y # the two numbers to be compared for equality + +int ex, ey +double x1, x2, normed_x, normed_y + +begin + if (x == y) + return (true) + + call rft_normd (x, normed_x, ex) + call rft_normd (y, normed_y, ey) + + if (ex != ey) + return (false) + else { + x1 = 1.0d0 + abs (normed_x - normed_y) + x2 = 1.0d0 + NEPSILON * EPSILOND + return (x1 <= x2) + } +end + + +# RFT_NORMED -- Normalize a double precision number x to the value normed_x, +# in the range [1-10]. Expon is returned such that x = normed_x * +# (10.0d0 ** expon). + +procedure rft_normd (x, normed_x, expon) + +double x # number to be normailized +double normed_x # normalized number +int expon # exponent + +double ax + +begin + ax = abs (x) + expon = 0 + + if (ax > 0) { + while (ax < (1.0d0 - NEPSILON * EPSILOND)) { + ax = ax * 10.0d0 + expon = expon - 1 + } + + while (ax >= (10.0d0 - NEPSILON * EPSILOND)) { + ax = ax / 10.0d0 + expon = expon + 1 + } + } + + if (x < 0) + normed_x = -ax + else + normed_x = ax +end + + +# RFT_TRIM_CARD -- Procedure to trim trailing whitespace from the card + +procedure rft_trim_card (incard, outcard, maxch) + +char incard[ARB] # input FITS card image +char outcard[ARB] # output FITS card +int maxch # maximum size of card + +int ip + +begin + ip = maxch + while (incard[ip] == ' ' || incard[ip] == '\t' || incard[ip] == '\0') + ip = ip - 1 + call amovc (incard, outcard, ip) + outcard[ip+1] = '\n' + outcard[ip+2] = EOS +end + + +# RFT_LAST_CARD -- Remove a partially written card from the data base + +procedure rft_last_user (user, maxch) + +char user[ARB] # user area +int maxch # maximum number of characters + +int ip + +begin + ip = maxch + while (user[ip] != '\n') + ip = ip - 1 + user[ip+1] = EOS +end diff --git a/pkg/obsolete/fits/fits_rimage.x b/pkg/obsolete/fits/fits_rimage.x new file mode 100644 index 00000000..e74e2dbb --- /dev/null +++ b/pkg/obsolete/fits/fits_rimage.x @@ -0,0 +1,605 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <mach.h> +include <fset.h> +include "rfits.h" + +# RFT_READ_IMAGE -- Convert FITS image pixels to IRAF image pixels. + +procedure rft_read_image (fits_fd, fits, im) + +int fits_fd # FITS file descriptor +pointer fits # FITS data structure +pointer im # IRAF image descriptor + +int i, npix, npix_record, blksize, ndummy +long v[IM_MAXDIM], nlines, il +pointer tempbuf, buf +real linemax, linemin, lirafmin, lirafmax +double dblank + +long clktime() +int fstati(), rft_init_read_pixels(), rft_read_pixels() + +errchk malloc, mfree, rft_init_read_pixels, rft_read_pixels, rft_lscale_pix +errchk rft_lchange_pix, rft_rchange_pix, rfit_dchange_pix, rft_put_image_line +errchk rft_pix_limits, rft_rscale_pix, rft_dscale_pix + +include "rfits.com" + +begin + # No pixel file was created. + if (NAXIS(im) == 0) { + call printf ("Warning: No pixel file created\n") + return + } + + # Initialize the header. + call rft_set_image_header (fits, im) + + # Compute the number of columns and lines in the image. + npix = NAXISN(im, 1) + nlines = 1 + do i = 2, NAXIS(im) + nlines = nlines * NAXISN(im, i) + lirafmax = -MAX_REAL + lirafmin = MAX_REAL + + # Compute the number of pixels per record and the number of records + # per output block. + + npix_record = len_record * FITS_BYTE / abs (BITPIX(fits)) + blksize = fstati (fits_fd, F_SZBBLK) + if (mod (blksize, FITS_RECORD) == 0) + blksize = blksize / FITS_RECORD + else + blksize = 1 + + # FITS data is converted to type LONG, REAL or DOUBLE. If BITPIX is + # not one of the MII types then rft_read_pixels returns an ERROR. + + call amovkl (long(1), v, IM_MAXDIM) + switch (BITPIX(fits)) { + case FITS_REAL: + + # Allocate temporary space. + call malloc (tempbuf, npix, TY_REAL) + + # Initialize the read. + i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, TY_REAL) + + # Turn on the ieee NaN mapping. + call ieesnanr (blank) + #call ieemapr (YES, NO) + #call ieezstatr () + NBPIX(im) = 0 + + # Allocate the space for the output line, read in the image + # line, convert from the ieee to native format, and compute the + # minimum and maximum. + + do il = 1, nlines { + call rft_put_image_line (im, buf, v, PIXTYPE(im)) + if (rft_read_pixels (fits_fd, Memr[tempbuf], npix, + NRECORDS(fits), blksize) != npix) + call printf ("Error reading FITS data\n") + if (SCALE(fits) == YES) + call rft_rscale_pix (Memr[tempbuf], buf, npix, + FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) + else + call rft_rchange_pix (Memr[tempbuf], buf, npix, PIXTYPE(im)) + call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) + lirafmax = max (lirafmax, linemax) + lirafmin = min (lirafmin, linemin) + } + + # Set the number of bad pixels. + call ieestatr (NBPIX(im), ndummy) + + # Free space. + call mfree (tempbuf, TY_REAL) + + case FITS_DOUBLE: + + # Allocate temporary space. + call malloc (tempbuf, npix, TY_DOUBLE) + + # Initialize the read. + i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, + TY_DOUBLE) + + # Turn on the ieee NaN mapping. + dblank = blank + call ieesnand (dblank) + #call ieemapd (YES, NO) + #call ieezstatd () + NBPIX(im) = 0 + + # Allocate the space for the output line, read in the image + # line, convert from the ieee to native format, and compute the + # minimum and maximum. + + do il = 1, nlines { + call rft_put_image_line (im, buf, v, PIXTYPE(im)) + if (rft_read_pixels (fits_fd, Memd[tempbuf], npix, + NRECORDS(fits), blksize) != npix) + call printf ("Error reading FITS data\n") + if (SCALE(fits) == YES) + call rft_dscale_pix (Memd[tempbuf], buf, npix, + FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) + else + call rft_dchange_pix (Memd[tempbuf], buf, npix, PIXTYPE(im)) + call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) + if (IS_INDEFR(linemax)) + lirafmax = INDEFR + else + lirafmax = max (lirafmax, linemax) + if (IS_INDEFR(linemin)) + lirafmin = INDEFR + else + lirafmin = min (lirafmin, linemin) + } + + # Set the number of bad pixels. + call ieestatd (NBPIX(im), ndummy) + + # Free space. + call mfree (tempbuf, TY_DOUBLE) + + default: + + # Allocate the required space. + call malloc (tempbuf, npix, TY_LONG) + + # Allocate the space for the output line, read in the image + # line, convert from the ieee to native format, and compute the + # minimum and maximum. + + i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, TY_LONG) + do il = 1, nlines { + call rft_put_image_line (im, buf, v, PIXTYPE(im)) + if (rft_read_pixels (fits_fd, Meml[tempbuf], npix, + NRECORDS(fits), blksize) != npix) + call printf ("Error reading FITS data\n") + if (SCALE(fits) == YES) + call rft_lscale_pix (Meml[tempbuf], buf, npix, + FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) + else + call rft_lchange_pix (Meml[tempbuf], buf, npix, PIXTYPE(im)) + if (BLANKS(fits) == YES) + call rft_map_blanks (Meml[tempbuf], buf, npix, PIXTYPE(im), + BLANK_VALUE(fits), blank, NBPIX(im)) + call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) + lirafmax = max (lirafmax, linemax) + lirafmin = min (lirafmin, linemin) + } + + # Free space. + call mfree (tempbuf, TY_LONG) + } + + IRAFMIN(im) = lirafmin + IRAFMAX(im) = lirafmax + LIMTIME(im) = clktime (long(0)) + + if (NBPIX (im) != 0) { + call printf ("Warning: %d bad pixels replaced in image\n") + call pargl (NBPIX (im)) + } + if (IS_INDEFR(lirafmax) || lirafmax > MAX_REAL) { + call printf ("Warning: image contains pixel values > %g\n") + call pargr (MAX_REAL) + } + if (IS_INDEFR(lirafmin) || lirafmin < -MAX_REAL) { + call printf ("Warning: image contains pixel values < %g\n") + call pargr (-MAX_REAL) + } +end + + +# RFT_SET_IMAGE_HEADER -- Set remaining header fields not set in +# rft_read_header. + +procedure rft_set_image_header (fits, im) + +pointer fits # FITS data structure +pointer im # IRAF image pointer + +include "rfits.com" + +begin + # Determine data type from BITPIX if user data type not specified. + + if (data_type == ERR) { + if (BITPIX(fits) < 0) { + if (abs (BITPIX(fits)) <= (SZ_REAL * SZB_CHAR * NBITS_BYTE)) + PIXTYPE(im) = TY_REAL + else + PIXTYPE(im) = TY_DOUBLE + } else if (SCALE(fits) == YES) { + PIXTYPE(im) = TY_REAL + } else { + if (BITPIX(fits) <= (SZ_SHORT * SZB_CHAR * NBITS_BYTE)) + PIXTYPE(im) = TY_SHORT + else + PIXTYPE(im) = TY_LONG + } + + } else + PIXTYPE(im) = data_type +end + + +# RFT_SET_PRECISION -- Procedure to determine the precision of the FITS data +# type. + +procedure rft_set_precision (bitpix, precision) + +int bitpix # FITS bits per pixel +int precision # FITS decimal digits of precision + +begin + switch (bitpix) { + case FITS_BYTE: + precision = FITSB_PREC + case FITS_SHORT: + precision = FITSS_PREC + case FITS_LONG: + precision = FITSL_PREC + default: + call error (16, "RFT_SET_PRECISION: Unknown FITS type") + } +end + + +# RFT_PUT_IMAGE_LINE -- Procedure to output an image line to and IRAF file. + +procedure rft_put_image_line (im, buf, v, data_type) + +pointer im # IRAF image descriptor +pointer buf # Pointer to output image line +long v[ARB] # imio pointer +int data_type # output pixel type + +int impnll(), impnlr(), impnld(), impnlx() +errchk impnll, impnlr, impnld, impnlx + +begin + switch (data_type) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + if (impnll (im, buf, v) == EOF) + call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") + case TY_REAL: + if (impnlr (im, buf, v) == EOF) + call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") + case TY_DOUBLE: + if (impnld (im, buf, v) == EOF) + call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") + case TY_COMPLEX: + if (impnlx (im, buf, v) == EOF) + call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") + default: + call error (10, "RFT_PUT_IMAGE_LINE: Unsupported IRAF image type") + } +end + + +# RFT_RSCALE_PIX -- Procedure to convert an IRAF image line from type real +# to the requested output data type with optional scaling using the +# FITS parameters BSCALE and BZERO. + +procedure rft_rscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) + +real inbuf[ARB] # buffer of FITS integers +pointer outbuf # pointer to output image line +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero +int data_type # IRAF image pixel type + +errchk altmdr, achtrl, amovr, achtrd, achtrx + +begin + switch (data_type) { + case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: + call altmdr (inbuf, inbuf, npix, bscale, bzero) + call achtrl (inbuf, Meml[outbuf], npix) + case TY_REAL: + call altmdr (inbuf, inbuf, npix, bscale, bzero) + call amovr (inbuf, Memr[outbuf], npix) + case TY_DOUBLE: + call altmdr (inbuf, inbuf, npix, bscale, bzero) + call achtrd (inbuf, Memd[outbuf], npix) + case TY_COMPLEX: + call altmdr (inbuf, inbuf, npix, bscale, bzero) + call achtrx (inbuf, Memx[outbuf], npix) + default: + call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") + } +end + + +# RFT_DSCALE_PIX -- Procedure to convert an IRAF image line from type double +# to the requested output data type with optional scaling using the +# FITS parameters BSCALE and BZERO. + +procedure rft_dscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) + +double inbuf[ARB] # buffer of FITS integers +pointer outbuf # pointer to output image line +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero +int data_type # IRAF image pixel type + +errchk altmd, achtdl, amovd, achtdr, achtdx + +begin + switch (data_type) { + case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: + call altmd (inbuf, inbuf, npix, bscale, bzero) + call achtdl (inbuf, Meml[outbuf], npix) + case TY_REAL: + call altmd (inbuf, inbuf, npix, bscale, bzero) + call achtdr (inbuf, Memr[outbuf], npix) + case TY_DOUBLE: + call altmd (inbuf, inbuf, npix, bscale, bzero) + call amovd (inbuf, Memd[outbuf], npix) + case TY_COMPLEX: + call altmd (inbuf, inbuf, npix, bscale, bzero) + call achtdx (inbuf, Memx[outbuf], npix) + default: + call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") + } +end + + + +# RFT_LSCALE_PIX -- Procedure to convert an IRAF image line from type long +# to the requested output data type with optional scaling using the +# FITS parameters BSCALE and BZERO. + +procedure rft_lscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) + +long inbuf[ARB] # buffer of FITS integers +pointer outbuf # pointer to output image line +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero +int data_type # IRAF image pixel type + +errchk achtll, achtlr, achtld, achtlx +errchk altml, altmr, altmd, altmx + +begin + switch (data_type) { + case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: + call achtll (inbuf, Meml[outbuf], npix) + call altml (Meml[outbuf], Meml[outbuf], npix, bscale, bzero) + case TY_REAL: + call altmlr (inbuf, Memr[outbuf], npix, bscale, bzero) + #call achtlr (inbuf, Memr[outbuf], npix) + #call altmdr (Memr[outbuf], Memr[outbuf], npix, bscale, bzero) + case TY_DOUBLE: + call achtld (inbuf, Memd[outbuf], npix) + call altmd (Memd[outbuf], Memd[outbuf], npix, bscale, bzero) + case TY_COMPLEX: + call achtlx (inbuf, Memx[outbuf], npix) + call altmx (Memx[outbuf], Memx[outbuf], npix, real (bscale), + real (bzero)) + default: + call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") + } +end + + +# RFT_RCHANGE_PIX -- Procedure to change a line of real numbers to the +# IRAF image type. + +procedure rft_rchange_pix (inbuf, outbuf, npix, data_type) + +real inbuf[ARB] # array of FITS integers +pointer outbuf # pointer to IRAF image line +int npix # number of pixels +int data_type # IRAF pixel type + +errchk achtrl, amovr, achtrd, achtrx + +begin + switch (data_type) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + call achtrl (inbuf, Meml[outbuf], npix) + case TY_REAL: + call amovr (inbuf, Memr[outbuf], npix) + case TY_DOUBLE: + call achtrd (inbuf, Memd[outbuf], npix) + case TY_COMPLEX: + call achtrx (inbuf, Memx[outbuf], npix) + default: + call error (10, "RFT_RCHANGE_LINE: Illegal IRAF image type") + } +end + + +# RFT_DCHANGE_PIX -- Procedure to change a line of double precision numbers +# to the IRAF image type. + +procedure rft_dchange_pix (inbuf, outbuf, npix, data_type) + +double inbuf[ARB] # array of FITS integers +pointer outbuf # pointer to IRAF image line +int npix # number of pixels +int data_type # IRAF pixel type + +errchk achtdl, achtdr, amovd, achtdx + +begin + switch (data_type) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + call achtdl (inbuf, Meml[outbuf], npix) + case TY_REAL: + call achtdr (inbuf, Memr[outbuf], npix) + case TY_DOUBLE: + call amovd (inbuf, Memd[outbuf], npix) + case TY_COMPLEX: + call achtdx (inbuf, Memx[outbuf], npix) + default: + call error (10, "RFT_DCHANGE_LINE: Illegal IRAF image type") + } +end + + + +# RFT_LCHANGE_PIX -- Procedure to change a line of long integers to the +# IRAF image type. + +procedure rft_lchange_pix (inbuf, outbuf, npix, data_type) + +long inbuf[ARB] # array of FITS integers +pointer outbuf # pointer to IRAF image line +int npix # number of pixels +int data_type # IRAF pixel type + +begin + switch (data_type) { + case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: + call achtll (inbuf, Meml[outbuf], npix) + case TY_REAL: + call achtlr (inbuf, Memr[outbuf], npix) + case TY_DOUBLE: + call achtld (inbuf, Memd[outbuf], npix) + case TY_COMPLEX: + call achtlx (inbuf, Memx[outbuf], npix) + default: + call error (10, "RFT_CHANGE_LINE: Illegal IRAF image type") + } +end + + +# RFT_MAP_BLANKS -- Map the blank pixels. Currently only the number of blank +# pixels is determined without an further mapping. + +procedure rft_map_blanks (a, buf, npts, pixtype, blank_value, blank, nbadpix) + +long a[ARB] # integer input buffer +pointer buf # pointer to output image buffer +int npts # number of points +int pixtype # image data type +long blank_value # FITS blank value +real blank # user blank value +long nbadpix # number of bad pixels + +int i + +begin + # Do blank mapping here + switch (pixtype) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + do i = 1, npts { + if (a[i] == blank_value) { + nbadpix = nbadpix + 1 + Meml[buf+i-1] = blank + } + } + case TY_REAL: + do i = 1, npts { + if (a[i] == blank_value) { + nbadpix = nbadpix + 1 + Memr[buf+i-1] = blank + } + } + case TY_DOUBLE: + do i = 1, npts { + if (a[i] == blank_value) { + nbadpix = nbadpix + 1 + Memd[buf+i-1] = blank + } + } + case TY_COMPLEX: + do i = 1, npts { + if (a[i] == blank_value) { + nbadpix = nbadpix + 1 + Memx[buf+i-1] = blank + } + } + } +end + + +# RFT_PIX_LIMITS -- Procedure to determine to maxmimum and minimum values in a +# line. Note that double precision is somewhat of a special case because +# MAX_DOUBLE is a lot less than the maximum permitted ieee numbers for iraf. + +procedure rft_pix_limits (buf, npix, pixtype, linemin, linemax) + +pointer buf # pointer to IRAF image line +int npix # number of pixels +int pixtype # output data type +real linemax, linemin # min and max pixel values + +long lmax, lmin +real rmax, rmin +double dmax, dmin +complex xmax, xmin + +begin + switch (pixtype) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + call aliml (Meml[buf], npix, lmin, lmax) + linemax = lmax + linemin = lmin + case TY_REAL: + call alimr (Memr[buf], npix, rmin, rmax) + linemax = rmax + linemin = rmin + case TY_DOUBLE: + call alimd (Memd[buf], npix, dmin, dmax) + if (dmax > MAX_REAL) + linemax = INDEFR + else + linemax = dmax + if (dmin < -MAX_REAL) + linemin = INDEFR + else + linemin = dmin + case TY_COMPLEX: + call alimx (Memx[buf], npix, xmin, xmax) + linemax = xmax + linemin = xmin + default: + call error (30, "RFT_PIX_LIMITS: Unknown IRAF type") + } +end + + +# ALTMDR -- procedure to scale a long vector into a real vector using +# double precision constants to preserve accuracy + +procedure altmlr (a, b, npix, bscale, bzero) + +long a[ARB] # input array +real b[ARB] # output array +int npix # number of pixels +double bscale, bzero # scaling parameters + +int i + +begin + do i = 1, npix + b[i] = a[i] * bscale + bzero +end + + +# ALTMDR -- procedure to scale a real vector with double precision constants. + +procedure altmdr (a, b, npix, bscale, bzero) + +real a[ARB] # input array +real b[ARB] # output array +int npix # number of pixels +double bscale, bzero # scaling parameters + +int i + +begin + do i = 1, npix + b[i] = a[i] * bscale + bzero +end diff --git a/pkg/obsolete/fits/fits_rpixels.x b/pkg/obsolete/fits/fits_rpixels.x new file mode 100644 index 00000000..dfce821d --- /dev/null +++ b/pkg/obsolete/fits/fits_rpixels.x @@ -0,0 +1,154 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <mii.h> +include <mach.h> + +# RFT_INIT_READ_PIXELS and READ_PIXELS -- Read pixel data with record buffering +# and data type conversion. The input data must meet the MII standard +# except for possibly in the case of integers having the least significant +# byte first. +# +# Read data in records of len_record and convert to the specified IRAF +# data type. Successive calls of rft_read_pixels returns the next npix pixels. +# Read_pixels returns EOF or the number of pixels converted. +# Init_read_pixels must be called before read_pixels. +# +# Error conditions are: +# 1. A short input record +# 2. Error in converting the pixels by miiup. +# +# This routine is based on the MII unpack routine which is machine dependent. +# The bitpix must correspond to an MII type. If the lsbf (least significant +# byte first) flag is YES then the pixels do not satisfy the MII standard. +# In this case the bytes are first swapped into most significant byte first +# before the MII unpack routine is called. + +int procedure rft_init_read_pixels (npix_record, bitpix, lsbf, spp_type) + +int npix_record # number of pixels per input record +int bitpix # bits per pixel (must correspond to an MII type) +int lsbf # byte swap? +int spp_type # SPP data type to be returned + +# entry rft_read_pixels (fd, buffer, npix) + +int rft_read_pixels +int fd # input file descriptor +char buffer[1] # output buffer +int npix # number of pixels to read + +int swap +int ty_mii, ty_spp, npix_rec, nch_rec, sz_rec, nchars, len_mii, recptr +int bufsize, i, n, ip, op +pointer mii, spp + +int rft_getbuf(), sizeof(), miilen() +errchk miilen, mfree, malloc, rft_getbuf, miiupk +data mii/NULL/, spp/NULL/ + +begin + ty_mii = bitpix + ty_spp = spp_type + swap = lsbf + npix_rec = npix_record + nch_rec = npix_rec * sizeof (ty_spp) + + len_mii = miilen (npix_rec, ty_mii) + sz_rec = len_mii * SZ_INT + + if (mii != NULL) + call mfree (mii, TY_INT) + call malloc (mii, len_mii, TY_INT) + + if (spp != NULL) + call mfree (spp, TY_CHAR) + call malloc (spp, nch_rec, TY_CHAR) + + ip = nch_rec + return (OK) + +entry rft_read_pixels (fd, buffer, npix, recptr, bufsize) + + nchars = npix * sizeof (ty_spp) + op = 0 + + repeat { + + # If data is exhausted read the next record + if (ip == nch_rec) { + + i = rft_getbuf (fd, Memi[mii], sz_rec, bufsize, recptr) + if (i == EOF) + return (EOF) + + if (swap == YES) + switch (ty_mii) { + case MII_SHORT: + call bswap2 (Memi[mii], 1, Memi[mii], 1, + sz_rec * SZB_CHAR) + case MII_LONG: + call bswap4 (Memi[mii], 1, Memi[mii], 1, + sz_rec * SZB_CHAR) + } + + call miiupk (Memi[mii], Memc[spp], npix_rec, ty_mii, ty_spp) + + ip = 0 + #recptr = recptr + 1 + } + + n = min (nch_rec - ip, nchars - op) + call amovc (Memc[spp+ip], buffer[1+op], n) + ip = ip + n + op = op + n + + } until (op == nchars) + + return (npix) +end + + +# RFT_GETBUF -- Procedure to get the buffer. + +int procedure rft_getbuf (fd, buf, sz_rec, bufsize, recptr) + +int fd # file descriptor +char buf[ARB] # buffer to be filled +int sz_rec # size in chars of record to be read +int bufsize # buffer size in records +int recptr # last successful FITS record read + +int i, nchars +int read(), fstati() +errchk read + +begin + nchars = 0 + repeat { + iferr { + i = read (fd, buf[nchars+1], sz_rec - nchars) + } then { + call printf ("Error reading FITS record %d\n") + if (mod (recptr + 1, bufsize) == 0) + call pargi ((recptr + 1) / bufsize) + else + call pargi ((recptr + 1) / bufsize + 1) + call fseti (fd, F_VALIDATE, fstati (fd, F_SZBBLK) / SZB_CHAR) + i = read (fd, buf[nchars+1], sz_rec - nchars) + } + + if (i == EOF) + break + else + nchars = nchars + i + + } until (nchars >= sz_rec) + + if ((i == EOF) && (nchars == 0)) + return (EOF) + else { + recptr = recptr + 1 + return (nchars) + } +end diff --git a/pkg/obsolete/fits/fits_wheader.x b/pkg/obsolete/fits/fits_wheader.x new file mode 100644 index 00000000..f00a0de6 --- /dev/null +++ b/pkg/obsolete/fits/fits_wheader.x @@ -0,0 +1,471 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <mach.h> +include <fset.h> +include "wfits.h" + +# WFT_WRITE_HEADER -- Write the FITS headers. The FITS header +# parameters are encoded one by one until the FITS END keyword is detected. +# If the long_header switch is set the full FITS header is printed on the +# standard output. If the short header parameter is specified only the image +# title and dimensions are printed. + +procedure wft_write_header (im, fits, fits_fd) + +pointer im # pointer to the IRAF image +pointer fits # pointer to the FITS structure +int fits_fd # the FITS file descriptor + +char card[LEN_CARD+1], trim_card[LEN_CARD+1] +int nrecords, recntr, cardptr, cardcnt, stat, cards_per_rec, i +int wft_card_encode(), wft_set_bitpix(), sizeof(), strncmp() +int wft_init_card_encode(), fstati() + +errchk wft_set_bitpix, wft_get_iraf_typestring, wft_set_scale, wft_set_blank +errchk wft_fits_set_scale, wft_init_card_encode, wft_card_encode +errchk wft_init_write_pixels, wft_write_pixels, wft_write_last_record + +include "wfits.com" + +begin + # SET the data and FITS bits per pixel. + + DATA_BITPIX(fits) = sizeof (PIXTYPE(im)) * SZB_CHAR * NBITS_BYTE + FITS_BITPIX(fits) = wft_set_bitpix (bitpix, PIXTYPE(im), + DATA_BITPIX(fits)) + + # Calculate the FITS bscale and bzero parameters. Notice for the + # time being that scaling is turned off if IEEE floating point + # output is selected. May decide to change this later after + # checking the specifications. + + if (FITS_BITPIX(fits) < 0) { + + IRAFMIN(fits) = IM_MIN(im) + IRAFMAX(fits) = IM_MAX(im) + SCALE(fits) = NO + BZERO(fits) = 0.0d0 + BSCALE(fits) = 1.0d0 + + } else if (autoscale == YES) { + + call wft_get_tape_limits (FITS_BITPIX(fits), TAPEMIN(fits), + TAPEMAX(fits)) + call wft_data_limits (im, IRAFMIN(fits), IRAFMAX(fits)) + call wft_fits_set_scale (im, DATA_BITPIX(fits), FITS_BITPIX(fits), + IRAFMIN(fits), IRAFMAX(fits), TAPEMIN(fits), TAPEMAX(fits), + SCALE(fits), BSCALE(fits), BZERO(fits)) + + } else { + + IRAFMIN(fits) = IM_MIN(im) + IRAFMAX(fits) = IM_MAX(im) + SCALE(fits) = scale + BZERO(fits) = bzero + BSCALE(fits) = bscale + } + + # If blanks in the image set the blank parameter. Currently information + # on blanks is not written out so this is effectively a null operation + # in IRAF. + + if (NBPIX(im) > 0) + call wft_set_blank (FITS_BITPIX(fits), BLANK(fits), + BLANK_STRING(fits)) + + # Set the IRAF datatype parameter. + call wft_get_iraf_typestring (PIXTYPE(im), TYPE_STRING(fits)) + + # Initialize the card counters. These counters are used only for + # information printed to the standard output. + + recntr = 1 + cardptr = 1 + cardcnt = 1 + cards_per_rec = len_record / LEN_CARD + + # Get set up to write the FITS header. Initialize for an ASCII write. + stat = wft_init_card_encode (im, fits) + if (make_image == YES) + call wft_init_wrt_pixels (len_record, TY_CHAR, FITS_BYTE, blkfac) + + # Print short header. + if (short_header == YES && long_header == NO) { + + call printf ("%-20.20s ") + call pargstr (OBJECT(im)) + do i = 1, NAXIS(im) { + if (i == 1) { + call printf ("Size = %d") + call pargl (NAXISN(im,i)) + } else { + call printf (" x %d") + call pargl (NAXISN(im,i)) + } + } + call printf ("\n") + + call strlwr (TYPE_STRING(fits)) + call printf ("\tpixtype=%s bitpix=%d") + call pargstr (TYPE_STRING(fits)) + call pargi (FITS_BITPIX(fits)) + + if (fstati (fits_fd, F_BLKSIZE) == 0) { + call printf (" blkfac=%d") + call pargi (blkfac) + } else + call printf (" blkfac=fixed") + + if (SCALE(fits) == YES) { + call printf (" bscale=%.7g bzero=%.7g\n") + call pargd (BSCALE(fits)) + call pargd (BZERO(fits)) + } else + call printf (" scaling=none\n") + call strupr (TYPE_STRING(fits)) + } + + # Write the cards to the FITS header. + repeat { + + # Encode the card. + stat = wft_card_encode (im, fits, card) + if (stat == NO) + next + + # Write the card to the output file if make_image is yes. + if (make_image == YES) + call wft_write_pixels (fits_fd, card, LEN_CARD) + + # Trim the card and write is to the standard output if + # long_header is yes. + + if (long_header == YES) { + call wft_trimstr (card, trim_card, LEN_CARD) + call printf ("%2d/%2d:-- %s\n") + call pargi (recntr) + call pargi (cardptr) + call pargstr (trim_card) + } + + if (mod (cardcnt, cards_per_rec) == 0) { + recntr = recntr + 1 + cardptr = 1 + } else + cardptr = cardptr + 1 + cardcnt = cardcnt + 1 + + } until (strncmp (card, "END ", LEN_KEYWORD) == 0) + + # Issue warning about possible precision loss. Comment this out + # for time being, since the short header was modified. + #if (SCALE(fits) == YES && bitpix != ERR) { + #call printf ( + #"\tDefault bitpix overridden: maximum precision loss ~%.7g\n") + #call pargd (BSCALE(fits)) + #} + + # Write the last header records. + if (make_image == YES) { + call wft_write_last_record (fits_fd, nrecords) + if (short_header == YES || long_header == YES) { + call printf ("\t%d Header ") + call pargi (nrecords) + } + } +end + + +# WFT_SET_BITPIX -- This procedure sets the FITS bitpix for each image based on +# either the user given value or the precision of the IRAF data. Notice that +# the user must explicitly set the bitpix parameter to -16 or -32 to select +# the IEEE output format. + +int procedure wft_set_bitpix (bitpix, datatype, data_bitpix) + +int bitpix # the user set bits per pixel, ERR or legal bitpix +int datatype # the IRAF image data type +int data_bitpix # the bits per pixel in the data + +begin + if (bitpix == ERR) { + switch (datatype) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + if (data_bitpix <= FITS_BYTE) + return (FITS_BYTE) + else if (data_bitpix <= FITS_SHORT) { + if (datatype == TY_USHORT) + return (FITS_LONG) + else + return (FITS_SHORT) + } else + return (FITS_LONG) + case TY_REAL, TY_COMPLEX: + return (FITS_REAL) + case TY_DOUBLE: + return (FITS_DOUBLE) + default: + call error (2, "SET_BITPIX: Unknown IRAF data type.") + } + } else + return (bitpix) +end + + +# WFT_GET_IRAF_TYPESTRING -- Procedure to set the iraf datatype keyword. +# Permitted strings are INTEGER, FLOATING or COMPLEX. + +procedure wft_get_iraf_typestring (datatype, type_str) + +int datatype # the IRAF data type +char type_str[ARB] # the output IRAF type string + +begin + switch (datatype) { + case TY_SHORT: + call strcpy ("SHORT", type_str, LEN_STRING) + case TY_USHORT: + call strcpy ("USHORT", type_str, LEN_STRING) + case TY_INT: + call strcpy ("INTEGER", type_str, LEN_STRING) + case TY_LONG: + call strcpy ("LONG", type_str, LEN_STRING) + case TY_REAL: + call strcpy ("REAL", type_str, LEN_STRING) + case TY_DOUBLE: + call strcpy ("DOUBLE", type_str, LEN_STRING) + case TY_COMPLEX: + call strcpy ("COMPLEX", type_str, LEN_STRING) + default: + call error (3, "IRAF_TYPE: Unknown IRAF image type.") + } +end + + +# WFT_FITS_SET_SCALE -- Procedure to set the FITS scaling parameters if +# autoscaling is enabled. + +procedure wft_fits_set_scale (im, data_bitpix, fits_bitpix, irafmin, irafmax, + tapemin, tapemax, scale, bscale, bzero ) + +pointer im # pointer to IRAF image +int data_bitpix # bits per pixel of data +int fits_bitpix # fits bits per pixel +real irafmin # minimum picture value +real irafmax # maximum picture value +double tapemin # minimum tape value +double tapemax # maximum tape value +int scale # scale data ? +double bscale # FITS bscale +double bzero # FITS bzero + +errchk wft_set_scale + +begin + switch (PIXTYPE(im)) { + case TY_SHORT, TY_INT, TY_LONG: + if (data_bitpix > fits_bitpix) { + scale = YES + call wft_set_scale (fits_bitpix, irafmin, irafmax, tapemin, + tapemax, bscale, bzero) + } else { + scale = NO + bscale = 1.0d0 + bzero = 0.0d0 + } + case TY_USHORT: + if (data_bitpix > fits_bitpix) { + scale = YES + call wft_set_scale (fits_bitpix, irafmin, irafmax, tapemin, + tapemax, bscale, bzero) + } else if (data_bitpix == fits_bitpix) { + scale = YES + bscale = 1.0d0 + bzero = 3.2768d4 + } else { + scale = NO + bscale = 1.0d0 + bzero = 0.0d0 + } + case TY_REAL, TY_DOUBLE, TY_COMPLEX: + scale = YES + call wft_set_scale (fits_bitpix, irafmin, irafmax, tapemin, tapemax, + bscale, bzero) + default: + call error (1, "WRT_HEADER: Unknown IRAF image type.") + } + +end + + +# WFT_SET_SCALE -- This procedure calculates bscale and bzero for each frame +# from the FITS bitpix and the maximum and minimum data values. + +procedure wft_set_scale (fits_bitpix, datamin, datamax, mintape, maxtape, + bscale, bzero) + +int fits_bitpix # the FITS integer bits per pixels +real datamax, datamin # the IRAF image data minimum and maximum +double mintape, maxtape # min and max FITS tape values +double bscale, bzero # the calculated bscale and bzero values + +double maxdata, mindata, num, denom +bool rft_equald() + +begin + # Calculate the maximum and minimum values in the data. + maxdata = datamax + abs ((datamax / (10.0 ** (NDIGITS_RP - 1)))) + mindata = datamin - abs ((datamin / (10.0 ** (NDIGITS_RP - 1)))) + denom = maxtape - mintape + num = maxdata - mindata + #denom = denom - denom / (1.0d1 ** (NDIGITS_RP - 1)) + #num = num + num / (1.0d1 ** (NDIGITS_RP - 1)) + + # Check for constant image case. + mindata = datamin + maxdata = datamax + if (rft_equald (num, 0.0d0)) { + bscale = 1.0d0 + bzero = maxdata + } else { + bscale = num / denom + bzero = (maxtape / denom) * mindata - (mintape / denom) * maxdata + } +end + + +# WFT_GET_TAPE_LIMITS -- Procedure for calculating the maximum and minimum FITS +# integer values from the FITS bitpix. + +procedure wft_get_tape_limits (fits_bitpix, mintape, maxtape) + +int fits_bitpix # the bits per pixel of a FITS integer +double maxtape, mintape # the maximun and minimum FITS tape integers + +begin + switch (fits_bitpix) { + case FITS_BYTE: + maxtape = BYTE_MAX + mintape = BYTE_MIN + case FITS_SHORT: + maxtape = SHORT_MAX + mintape = SHORT_MIN + case FITS_LONG: + maxtape = LONG_MAX + mintape = LONG_MIN + default: + call error (4, "TAPE_LIMITS: Unknown FITS type.") + } +end + + +# WFT_SET_BLANK -- Determine the FITS integer value for a blank pixel from the +# FITS bitpix. Notice that these are null ops for IEEE floating point format. + +procedure wft_set_blank (fits_bitpix, blank, blank_str) + +int fits_bitpix # the requested FITS bits per pixel +long blank # the FITS integer value of a blank pixel +char blank_str[ARB] # the encoded FITS integer value of a blank pixel + +begin + switch (fits_bitpix) { + case FITS_BYTE: + blank = long (BYTE_BLANK) + call strcpy ("0", blank_str, LEN_BLANK) + case FITS_SHORT: + blank = long (SHORT_BLANK) + call strcpy ("-32768", blank_str, LEN_BLANK) + case FITS_LONG: + blank = long (LONG_BLANK) + call strcpy ("-2147483648", blank_str, LEN_BLANK) + case FITS_REAL: + blank = INDEFL + call strcpy ("", blank_str, LEN_BLANK) + case FITS_DOUBLE: + blank = INDEFL + call strcpy ("", blank_str, LEN_BLANK) + default: + call error (5, "SET_BLANK: Unknown FITS type.") + } +end + + +# WFT_INIT_CARD_ENCODE -- This procedure initializes the card encoding +# procedure. The cards counters are initialized and the number of history cards +# calculated. + +int procedure wft_init_card_encode (im, fits) + +# both entry points +pointer im # pointer to the IRAF image +pointer fits # pointer to the WFITS structure + +# entry wft_card_encode +int wft_card_encode # entry point +char card[LEN_CARD+1] # string containing the card image + +int cardno, axisno, optiono, hist_ptr, unknown_ptr +int nstandard, noptions, stat +int wft_standard_card(), wft_option_card(), wft_last_card() +int wft_history_card(), wft_unknown_card() +errchk wft_standard_card, wft_option_card, wft_history_card +errchk wft_unknown_card, wft_last_card + +begin + # Initialize the card pointers. + cardno = 1 + axisno = 1 + optiono = 1 + unknown_ptr = 1 + hist_ptr = 1 + + # Initilaize the card counters. + nstandard = 3 + NAXIS(im) + noptions = NOPTIONS + nstandard + + return (YES) + + +# WFT_CARD_ENCODE -- Procedure to encode the FITS header parameters into +# FITS card images. + +entry wft_card_encode (im, fits, card) + + # Fetch the appropriate FITS header card image. + if (cardno <= nstandard) { + stat = wft_standard_card (cardno, im, fits, axisno, card) + } else if (cardno <= noptions) { + stat = wft_option_card (im, fits, optiono, card) + } else if (wft_unknown_card (im, unknown_ptr, card) == YES) { + stat = YES + } else if (wft_history_card (im, hist_ptr, card) == YES) { + stat = YES + } else { + stat = wft_last_card (card) + } + + cardno = cardno + 1 + + return (stat) +end + + +# WFT_TRIMSTR -- Procedure to trim trailing blanks from a fixed size string. + +procedure wft_trimstr (instr, outstr, nchars) + +char instr[ARB] # input string +char outstr[ARB] # output string +int nchars # last character of instr + +int ip + +begin + call strcpy (instr, outstr, nchars) + ip = nchars + while (outstr[ip] == ' ') + ip = ip - 1 + outstr[ip+1] = EOS +end diff --git a/pkg/obsolete/fits/fits_wimage.x b/pkg/obsolete/fits/fits_wimage.x new file mode 100644 index 00000000..539114ea --- /dev/null +++ b/pkg/obsolete/fits/fits_wimage.x @@ -0,0 +1,416 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> +include "wfits.h" + +# WFT_WRITE_IMAGE -- Procedure to convert IRAF image data to FITS format line by +# line. + +procedure wft_write_image (im, fits, fits_fd) + +pointer im # IRAF image descriptor +pointer fits # FITS data structure +int fits_fd # FITS file descriptor + +int npix, nlines, npix_record, i, stat, nrecords +long v[IM_MAXDIM] +pointer tempbuf, buf + +int wft_get_image_line() +errchk malloc, mfree, wft_get_image_line, wft_lscale_line, wft_long_line +errchk wft_init_write_pixels, wft_write_pixels, wft_write_last_record +errchk wft_rscale_line, wft_dscale_line + +include "wfits.com" + +begin + if (NAXIS(im) == 0) + return + + # Initialize. + npix = NAXISN(im,1) + nlines = 1 + do i = 2, NAXIS(im) + nlines = nlines * NAXISN(im, i) + npix_record = len_record * FITS_BYTE / abs (FITS_BITPIX(fits)) + + call amovkl (long(1), v, IM_MAXDIM) + switch (FITS_BITPIX(fits)) { + case FITS_REAL: + + # Allocate temporary space. + call malloc (tempbuf, npix, TY_REAL) + + # Initialize the pixel write. + call wft_init_write_pixels (npix_record, TY_REAL, + FITS_BITPIX(fits), blkfac) + + # For the time being explicitly turn off ieee NaN mapping. + call ieemapr (NO, NO) + + # Scale the lines, deal with the blanks via the ieee code which + # is currently turned off, and write the output records. + + do i = 1, nlines { + iferr (stat = wft_get_image_line (im, buf, v, PIXTYPE(im))) { + call erract (EA_WARN) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + } + if (stat == EOF ) + return + if (stat != npix) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + if (SCALE(fits) == YES) + call wft_rscale_line (buf, Memr[tempbuf], npix, + 1. / BSCALE(fits), -BZERO(fits), PIXTYPE(im)) + else + call wft_real_line (buf, Memr[tempbuf], npix, PIXTYPE(im)) + call wft_write_pixels (fits_fd, Memr[tempbuf], npix) + } + + # Free space. + call mfree (tempbuf, TY_REAL) + + case FITS_DOUBLE: + + # Allocate temporary space. + call malloc (tempbuf, npix, TY_DOUBLE) + + # Initialize the pixel write. + call wft_init_write_pixels (npix_record, TY_DOUBLE, + FITS_BITPIX(fits), blkfac) + + # For the time being explicitly turn off ieee NaN mapping. + call ieemapd (NO, NO) + + # Scale the lines, deal with the blanks via the ieee code which + # is currently turned off, and write the output records. + + do i = 1, nlines { + iferr (stat = wft_get_image_line (im, buf, v, PIXTYPE(im))) { + call erract (EA_WARN) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + } + if (stat == EOF ) + return + if (stat != npix) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + if (SCALE(fits) == YES) + call wft_dscale_line (buf, Memd[tempbuf], npix, + 1. / BSCALE(fits), -BZERO(fits), PIXTYPE(im)) + else + call wft_double_line (buf, Memd[tempbuf], npix, + PIXTYPE(im)) + call wft_write_pixels (fits_fd, Memd[tempbuf], npix) + } + + # Free space. + call mfree (tempbuf, TY_DOUBLE) + + default: + + # Allocate temporary space. + call malloc (tempbuf, npix, TY_LONG) + + # Scale the line, deal with the blanks, and write the output + # record. At the moement blanks are not dealt with. + + call wft_init_write_pixels (npix_record, TY_LONG, FITS_BITPIX(fits), + blkfac) + do i = 1, nlines { + iferr (stat = wft_get_image_line (im, buf, v, PIXTYPE(im))) { + call erract (EA_WARN) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + } + if (stat == EOF ) + return + if (stat != npix) + call error (10, "WRT_IMAGE: Error writing IRAF image.") + if (SCALE(fits) == YES) + call wft_lscale_line (buf, Meml[tempbuf], npix, + 1. / BSCALE(fits), -BZERO(fits), PIXTYPE(im)) + else + call wft_long_line (buf, Meml[tempbuf], npix, PIXTYPE(im)) + # call map_blanks (im, Meml[tempbuf], blank) + call wft_write_pixels (fits_fd, Meml[tempbuf], npix) + } + # Free space. + call mfree (tempbuf, TY_LONG) + } + + # Write the final record. + call wft_write_last_record (fits_fd, nrecords) + if (short_header == YES || long_header == YES) { + call printf ("%d Data logical (2880 byte) records written\n") + call pargi (nrecords) + } +end + + +# WFT_GET_IMAGE_LINE -- Procedure to fetch the next image line. + +int procedure wft_get_image_line (im, buf, v, datatype) + +pointer im # IRAF image descriptor +pointer buf # pointer to image line +long v[ARB] # imio dimension descriptor +int datatype # IRAF image data type + +int npix +int imgnll(), imgnlr(), imgnld(), imgnlx() +errchk imgnll, imgnlr, imgnld, imgnlx + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: + npix = imgnll (im, buf, v) + case TY_REAL: + npix = imgnlr (im, buf, v) + case TY_DOUBLE: + npix = imgnld (im, buf, v) + case TY_COMPLEX: + npix = imgnlx (im, buf, v) + default: + call error (11, "GET_IMAGE_LINE: Unknown IRAF image type.") + } + + return (npix) +end + + +# WFT_RSCALE_LINE -- This procedure converts the IRAF data to type real +# and scales by the FITS parameters bscale and bzero. + +procedure wft_rscale_line (buf, outbuffer, npix, bscale, bzero, datatype) + +pointer buf # pointer to IRAF image line +real outbuffer[ARB] # FITS integer buffer +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero parameters +int datatype # data type of image + +errchk achtlr, altadr, amovr, achtdr, acthxr + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call achtlr (Meml[buf], outbuffer, npix) + call altadr (outbuffer, outbuffer, npix, bzero, bscale) + case TY_REAL: + call amovr (Memr[buf], outbuffer, npix) + call altadr (outbuffer, outbuffer, npix, bzero, bscale) + case TY_DOUBLE: + call achtdr (Memd[buf], outbuffer, npix) + call altadr (outbuffer, outbuffer, npix, bzero, bscale) + case TY_COMPLEX: + call achtxr (Memx[buf], outbuffer, npix) + call altadr (outbuffer, outbuffer, npix, bzero, bscale) + default: + call error (12, "WFT_RSCALE_LINE: Unknown IRAF image type.") + } +end + + +# WFT_DSCALE_LINE -- This procedure converts the IRAF data to type double with +# after scaling by the FITS parameters bscale and bzero. + +procedure wft_dscale_line (buf, outbuffer, npix, bscale, bzero, datatype) + +pointer buf # pointer to IRAF image line +double outbuffer[ARB] # FITS integer buffer +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero parameters +int datatype # data type of image + +errchk achtld, altad, amovd, achtrd, achtxd + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call achtld (Meml[buf], outbuffer, npix) + call altad (outbuffer, outbuffer, npix, bzero, bscale) + case TY_REAL: + call achtrd (Memr[buf], outbuffer, npix) + call altad (outbuffer, outbuffer, npix, bzero, bscale) + case TY_DOUBLE: + call amovd (Memd[buf], outbuffer, npix) + call altad (outbuffer, outbuffer, npix, bzero, bscale) + case TY_COMPLEX: + call achtxd (Memx[buf], outbuffer, npix) + call altad (outbuffer, outbuffer, npix, bzero, bscale) + default: + call error (12, "WFT_DSCALE_LINE: Unknown IRAF image type.") + } +end + + +# WFT_LSCALE_LINE -- This procedure converts the IRAF data to type long with +# after scaling by the FITS parameters bscale and bzero. + +procedure wft_lscale_line (buf, outbuffer, npix, bscale, bzero, datatype) + +pointer buf # pointer to IRAF image line +long outbuffer[ARB] # FITS integer buffer +int npix # number of pixels +double bscale, bzero # FITS bscale and bzero parameters +int datatype # data type of image + +errchk altal, amovl, altadr, achtrl, altad, achtdl, altax, achtxl + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call altal (Meml[buf], Meml[buf], npix, bzero, bscale) + call amovl (Meml[buf], outbuffer, npix) + case TY_REAL: + call altarl (Memr[buf], outbuffer, npix, bzero, bscale) + #call altadr (Memr[buf], Memr[buf], npix, bzero, bscale) + #call achtrl (Memr[buf], outbuffer, npix) + case TY_DOUBLE: + call altad (Memd[buf], Memd[buf], npix, bzero, bscale) + call achtdl (Memd[buf], outbuffer, npix) + case TY_COMPLEX: + call altadx (Memx[buf], Memx[buf], npix, bzero, bscale) + call achtxl (Memx[buf], outbuffer, npix) + default: + call error (12, "WFT_LSCALE_LINE: Unknown IRAF image type.") + } +end + + +# WFT_REAL_LINE -- This procedure converts the IRAF image line to type long with +# no scaling. + +procedure wft_real_line (buf, outbuffer, npix, datatype) + +pointer buf # pointer to IRAF image line +real outbuffer[ARB] # buffer of FITS integers +int npix # number of pixels +int datatype # IRAF image datatype + +errchk achtlr, achtdr, amovr, achtxr + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call achtlr (Meml[buf], outbuffer, npix) + case TY_REAL: + call amovr (Memr[buf], outbuffer, npix) + case TY_DOUBLE: + call achtdr (Memd[buf], outbuffer, npix) + case TY_COMPLEX: + call achtxr (Memx[buf], outbuffer, npix) + default: + call error (13, "WFT_REAL_LINE: Unknown IRAF data type.") + } +end + + +# WFT_DOUBLE_LINE -- This procedure converts the IRAF image line to type long +# with no scaling. + +procedure wft_double_line (buf, outbuffer, npix, datatype) + +pointer buf # pointer to IRAF image line +double outbuffer[ARB] # buffer of FITS integers +int npix # number of pixels +int datatype # IRAF image datatype + +errchk achtld, achtrd, amovd, achtxd + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call achtld (Meml[buf], outbuffer, npix) + case TY_REAL: + call achtrd (Memr[buf], outbuffer, npix) + case TY_DOUBLE: + call amovd (Memd[buf], outbuffer, npix) + case TY_COMPLEX: + call achtxd (Memx[buf], outbuffer, npix) + default: + call error (13, "WFT_DOUBLE_LINE: Unknown IRAF data type.") + } +end + + +# WFT_LONG_LINE -- This procedure converts the IRAF image line to type long with +# no scaling. + +procedure wft_long_line (buf, outbuffer, npix, datatype) + +pointer buf # pointer to IRAF image line +long outbuffer[ARB] # buffer of FITS integers +int npix # number of pixels +int datatype # IRAF image datatype + +errchk amovl, achtrl, achtdl, achtxl + +begin + switch (datatype) { + case TY_SHORT, TY_INT, TY_LONG, TY_USHORT: + call amovl (Meml[buf], outbuffer, npix) + case TY_REAL: + call achtrl (Memr[buf], outbuffer, npix) + case TY_DOUBLE: + call achtdl (Memd[buf], outbuffer, npix) + case TY_COMPLEX: + call achtxl (Memx[buf], outbuffer, npix) + default: + call error (13, "WFT_LONG_LINE: Unknown IRAF data type.") + } +end + + +# ALTARL -- Procedure to linearly scale a real vector into a long vector +# using double precision constants to preserve precision. + +procedure altarl (a, b, npix, k1, k2) + +real a[ARB] # input vector +long b[ARB] # output vector +int npix # number of pixels +double k1, k2 # scaling factors + +int i + +begin + do i = 1, npix + b[i] = (a[i] + k1) * k2 +end + + +# ALTADR -- Procedure to linearly scale a real vector in double precision + +procedure altadr (a, b, npix, k1, k2) + +real a[ARB] # input vector +real b[ARB] # output vector +int npix # number of pixels +double k1, k2 # scaling factors + +int i + +begin + do i = 1, npix + b[i] = (a[i] + k1) * k2 +end + + +# ALTADX -- Procedure to linearly scale a complex vector in double precision + +procedure altadx (a, b, npix, k1, k2) + +complex a[ARB] # input vector +complex b[ARB] # output vector +int npix # number of pixels +double k1, k2 # scaling factors + +int i + +begin + do i = 1, npix + b[i] = (a[i] + k1) * k2 +end + diff --git a/pkg/obsolete/fits/fits_wpixels.x b/pkg/obsolete/fits/fits_wpixels.x new file mode 100644 index 00000000..11d4fd0a --- /dev/null +++ b/pkg/obsolete/fits/fits_wpixels.x @@ -0,0 +1,162 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include "wfits.h" + +# WFT_INIT_WRITE_PIXELS -- This procedure calculates the input and +# output buffer sizes based in the spp and mii data types and allocates +# the required space. + +procedure wft_init_write_pixels (npix_record, spp_type, bitpix, blkfac) + +int npix_record # number of data pixels per record +int spp_type # pixel data type +int bitpix # output bits per pixel +int blkfac # fits blocking factor (0 for disk) + +# entry wft_write_pixels, wft_write_last_record + +int fd # output file descriptor +char buffer[1] # input buffer +int npix # number of pixels in the input buffer +int nrecords # number of FITS records written + +char blank, zero +int ty_mii, ty_spp, npix_rec, nch_rec, len_mii, sz_rec, nchars, n, nrec +int bf, szblk +pointer spp, mii, ip, op + +int sizeof(), miilen(), fstati() +long note() +errchk malloc, mfree, write, miipak, amovc +data mii /NULL/, spp/NULL/ + +begin + # Change input parameters into local variables. + ty_mii = bitpix + ty_spp = spp_type + npix_rec = npix_record + nch_rec = npix_rec * sizeof (ty_spp) + bf = blkfac + blank = ' ' + zero = 0 + + # Compute the size of the mii buffer. + len_mii = miilen (npix_rec, ty_mii) + sz_rec = len_mii * SZ_INT + + # Allocate space for the buffers. + if (spp != NULL) + call mfree (spp, TY_CHAR) + call malloc (spp, nch_rec, TY_CHAR) + if (mii != NULL) + call mfree (mii, TY_INT) + call malloc (mii, len_mii, TY_INT) + + op = 0 + nrec = 0 + + return + +# WFT_WRITE_PIXELS -- Wft_wrt_pixels gets an image line and places it in the +# output buffer. When the output buffer is full the data are packed by the mii +# routines and written to the specified output. + +entry wft_write_pixels (fd, buffer, npix) + + nchars = npix * sizeof (ty_spp) + ip = 0 + + repeat { + + # Fill output buffer. + n = min (nch_rec - op, nchars - ip) + call amovc (buffer[1 + ip], Memc[spp + op], n) + ip = ip + n + op = op + n + + # Write output record. + if (op == nch_rec) { + call miipak (Memc[spp], Memi[mii], npix_rec, ty_spp, ty_mii) + iferr (call write (fd, Memi[mii], sz_rec)) { + if (ty_spp == TY_CHAR) { + call printf (" File incomplete: %d logical header") + call pargi (nrec) + call printf (" (2880 byte) records written\n") + call error (18, + "WRT_RECORD: Error writing header record.") + } else { + call printf (" File incomplete: %d logical data") + call pargi (nrec) + call printf (" (2880 byte) records written\n") + call error (19, + "WRT_RECORD: Error writing data record.") + } + } + + nrec = nrec + 1 + op = 0 + } + + } until (ip == nchars) + + return + + +# WFT_WRITE_LAST_RECORD -- Procedure to write the last partially filled record +# to tape. Fill with blanks if header record otherwise fill with zeros. + +entry wft_write_last_record (fd, nrecords) + + if (op != 0) { + + # Blank or zero fill the last record. + n = nch_rec - op + if (ty_spp == TY_CHAR) + call amovkc (blank, Memc[spp + op], n) + else + call amovkc (zero, Memc[spp + op], n) + + # Write last record. + call miipak (Memc[spp], Memi[mii], npix_rec, ty_spp, ty_mii) + iferr (call write (fd, Memi[mii], sz_rec)) { + if (ty_spp == TY_CHAR) { + call printf ("File incomplete: %d logical header") + call pargi (nrec) + call printf (" (2880 byte) records written\n") + call error (18, + "WRT_LAST_RECORD: Error writing last header record.") + } else { + call printf ("File incomplete: %d logical data") + call pargi (nrec) + call printf (" (2880 byte) records written\n") + call error (19, + "WRT_LAST_RECORD: Error writing last data record.") + } + } + + + nrec = nrec + 1 + + # Pad out the record if the blocking is non-standard. + szblk = fstati (fd, F_BUFSIZE) * SZB_CHAR + if ((bf > 0) && mod (szblk, FITS_RECORD) != 0 && + (ty_spp != TY_CHAR)) { + szblk = szblk / SZB_CHAR + n = note (fd) - 1 + if (mod (n, szblk) == 0) + n = 0 + else + n = szblk - mod (n, szblk) + for (op = 1; op <= n; op = op + nch_rec) { + szblk = min (nch_rec, n - op + 1) + call amovkc (zero, Memc[spp], szblk) + #call write (fd, Memc[spp], szblk) + } + } + + } + + nrecords = nrec +end diff --git a/pkg/obsolete/fits/fits_write.x b/pkg/obsolete/fits/fits_write.x new file mode 100644 index 00000000..6887ead0 --- /dev/null +++ b/pkg/obsolete/fits/fits_write.x @@ -0,0 +1,156 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <error.h> +include <mach.h> +include <imhdr.h> +include "wfits.h" + +# WFT_WRITE_FITZ -- Procedure to convert a single IRAF file to a FITS file. +# If the make_image switch is set the header and pixel files are output +# to the output destination. If the make_image switch is off the header +# is printed to the standard output. + +procedure wft_write_fitz (iraf_file, fits_file) + +char iraf_file[ARB] # IRAF file name +char fits_file[ARB] # FITS file name + +int fits_fd, chars_rec, nchars, ip, min_lenuserarea +pointer im, sp, fits, envstr + +int mtfile(), mtopen(), open(), fnldir(), envfind(), ctoi() +pointer immap() +errchk immap, imunmap, open, mtopen, close, smark, salloc, sfree +errchk delete, wft_write_header, wft_write_image, wft_data_limits + +include "wfits.com" + +begin + # Allocate memory for program data structure. + call smark (sp) + call salloc (fits, LEN_FITS, TY_STRUCT) + call salloc (envstr, SZ_FNAME, TY_CHAR) + + # Construct the old iraf name by removing the directory + # specification. + + call imgcluster (iraf_file, IRAFNAME(fits), SZ_FNAME) + nchars = fnldir (IRAFNAME(fits), IRAFNAME(fits), SZ_FNAME) + call strcpy (iraf_file[nchars+1], IRAFNAME(fits), SZ_FNAME) + + # Open the input image. + if (envfind ("min_lenuserarea", Memc[envstr], SZ_FNAME) > 0) { + ip = 1 + if (ctoi (Memc[envstr], ip, min_lenuserarea) <= 0) + min_lenuserarea = LEN_USERAREA + else + min_lenuserarea = max (LEN_USERAREA, min_lenuserarea) + } else + min_lenuserarea = LEN_USERAREA + im = immap (iraf_file, READ_ONLY, min_lenuserarea) + + # Open the output file. Check whether the output file is a magtape + # device or a binary file. If the output file is magtape check + # for a legal blocking factor. + + if (make_image == NO) + call strcpy ("dev$null", fits_file, SZ_FNAME) + + if (mtfile (fits_file) == YES) { + chars_rec = (blkfac * len_record * FITS_BYTE) / (SZB_CHAR * + NBITS_BYTE) + fits_fd = mtopen (fits_file, WRITE_ONLY, chars_rec) + } else + fits_fd = open (fits_file, NEW_FILE, BINARY_FILE) + + # Write header and image. + iferr { + + if (short_header == YES || long_header == YES) { + if (make_image == YES) { + call printf (" -> %s ") + call pargstr (fits_file) + } + if (long_header == YES) + call printf ("\n") + } + call flush (STDOUT) + + call wft_write_header (im, fits, fits_fd) + if (make_image == YES) + call wft_write_image (im, fits, fits_fd) + + if (long_header == YES) + call printf ("\n") + + } then { + + # Print the error message. + call flush (STDOUT) + call erract (EA_WARN) + + # Close files and cleanup. + call imunmap (im) + call close (fits_fd) + if (make_image == NO) + call delete (fits_file) + call sfree (sp) + + # Assert an error. + call erract (EA_ERROR) + + } else { + + # Close files and cleanup. + call imunmap (im) + call close (fits_fd) + if (make_image == NO) + call delete (fits_file) + call sfree (sp) + } + +end + + +# WFT_DATA_LIMITS -- Procedure to calculate the maximum and minimum data values +# in an IRAF image. Values are only calculated if the max and min are unknown +# or the image has been modified since the last values were calculated. + +procedure wft_data_limits (im, irafmin, irafmax) + +pointer im # image pointer +real irafmin # minimum picture value +real irafmax # maximum picture value + +int npix +long v[IM_MAXDIM] +pointer buf +real maxval, minval +int imgnlr() +errchk imgnlr + +begin + # Compute the data minimum and maximum if the image values + # are undefined out-of-date. + + if (LIMTIME(im) < MTIME(im) && NAXIS(im) > 0) { + + irafmax = -MAX_REAL + irafmin = MAX_REAL + npix = NAXISN(im,1) + + call amovkl (long(1), v, IM_MAXDIM) + while (imgnlr (im, buf, v) != EOF) { + call alimr (Memr[buf], npix, minval, maxval) + irafmin = min (irafmin, minval) + irafmax = max (irafmax, maxval) + } + + } else { + + irafmax = IM_MAX(im) + irafmin = IM_MIN(im) + + } +end diff --git a/pkg/obsolete/fits/mkpkg b/pkg/obsolete/fits/mkpkg new file mode 100644 index 00000000..dd583c01 --- /dev/null +++ b/pkg/obsolete/fits/mkpkg @@ -0,0 +1,23 @@ +# Fits Library + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + fits_cards.x wfits.com wfits.h <imhdr.h> + fits_params.x wfits.h <time.h> + fits_read.x rfits.com rfits.h <error.h> <fset.h> <imhdr.h> + fits_rheader.x rfits.com rfits.h rfits.com <ctype.h> <imhdr.h>\ + <imio.h> <mach.h> + fits_rimage.x rfits.com rfits.h <imhdr.h> <fset.h> <mach.h> + fits_rpixels.x <fset.h> <mach.h> <mii.h> + fits_wheader.x wfits.com wfits.h <fset.h> <imhdr.h> <mach.h> + fits_wimage.x wfits.com wfits.h <error.h> <imhdr.h> + fits_wpixels.x wfits.h <fset.h> <mach.h> + fits_write.x <error.h> wfits.com wfits.h <fset.h> <imhdr.h> <mach.h> + ranges.x <mach.h> <ctype.h> + t_rfits.x rfits.com rfits.h <error.h> <fset.h> + t_wfits.x wfits.com wfits.h <error.h> <fset.h> <mach.h> + ; diff --git a/pkg/obsolete/fits/ranges.x b/pkg/obsolete/fits/ranges.x new file mode 100644 index 00000000..b3812cd1 --- /dev/null +++ b/pkg/obsolete/fits/ranges.x @@ -0,0 +1,234 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <ctype.h> + +define FIRST 1 # Default starting range +define LAST MAX_INT # Default ending range +define STEP 1 # Default step + +# DECODE_RANGES -- Parse a string containing a list of integer numbers or +# ranges, delimited by either spaces or commas. Return as output a list +# of ranges defining a list of numbers, and the count of list numbers. +# Range limits must be positive nonnegative integers. ERR is returned as +# the function value if a conversion error occurs. The list of ranges is +# delimited by a single NULL. + +int procedure decode_ranges (range_string, ranges, max_ranges, nvalues) + +char range_string[ARB] # Range string to be decoded +int ranges[3, max_ranges] # Range array +int max_ranges # Maximum number of ranges +int nvalues # The number of values in the ranges + +int ip, nrange, first, last, step, ctoi() + +begin + ip = 1 + nvalues = 0 + + do nrange = 1, max_ranges - 1 { + # Defaults to all positive integers + first = FIRST + last = LAST + step = STEP + + # Skip delimiters + while (IS_WHITE(range_string[ip]) || range_string[ip] == ',') + ip = ip + 1 + + # Get first limit. + # Must be a number, '-', 'x', or EOS. If not return ERR. + if (range_string[ip] == EOS) { # end of list + if (nrange == 1) { + # Null string defaults + ranges[1, 1] = first + ranges[2, 1] = last + ranges[3, 1] = step + ranges[1, 2] = NULL + nvalues = nvalues + abs (last-first) / step + 1 + return (OK) + } else { + ranges[1, nrange] = NULL + return (OK) + } + } else if (range_string[ip] == '-') + ; + else if (range_string[ip] == 'x') + ; + else if (IS_DIGIT(range_string[ip])) { # ,n.. + if (ctoi (range_string, ip, first) == 0) + return (ERR) + } else + return (ERR) + + # Skip delimiters + while (IS_WHITE(range_string[ip]) || range_string[ip] == ',') + ip = ip + 1 + + # Get last limit + # Must be '-', or 'x' otherwise last = first. + if (range_string[ip] == 'x') + ; + else if (range_string[ip] == '-') { + ip = ip + 1 + while (IS_WHITE(range_string[ip]) || range_string[ip] == ',') + ip = ip + 1 + if (range_string[ip] == EOS) + ; + else if (IS_DIGIT(range_string[ip])) { + if (ctoi (range_string, ip, last) == 0) + return (ERR) + } else if (range_string[ip] == 'x') + ; + else + return (ERR) + } else + last = first + + # Skip delimiters + while (IS_WHITE(range_string[ip]) || range_string[ip] == ',') + ip = ip + 1 + + # Get step. + # Must be 'x' or assume default step. + if (range_string[ip] == 'x') { + ip = ip + 1 + while (IS_WHITE(range_string[ip]) || range_string[ip] == ',') + ip = ip + 1 + if (range_string[ip] == EOS) + ; + else if (IS_DIGIT(range_string[ip])) { + if (ctoi (range_string, ip, step) == 0) + ; + } else if (range_string[ip] == '-') + ; + else + return (ERR) + } + + # Output the range triple. + ranges[1, nrange] = first + ranges[2, nrange] = last + ranges[3, nrange] = step + nvalues = nvalues + abs (last-first) / step + 1 + } + + return (ERR) # ran out of space +end + + +# GET_NEXT_NUMBER -- Given a list of ranges and the current file number, +# find and return the next file number. Selection is done in such a way +# that list numbers are always returned in monotonically increasing order, +# regardless of the order in which the ranges are given. Duplicate entries +# are ignored. EOF is returned at the end of the list. + +int procedure get_next_number (ranges, number) + +int ranges[ARB] # Range array +int number # Both input and output parameter + +int ip, first, last, step, next_number, remainder + +begin + # If number+1 is anywhere in the list, that is the next number, + # otherwise the next number is the smallest number in the list which + # is greater than number+1. + + number = number + 1 + next_number = MAX_INT + + for (ip=1; ranges[ip] != NULL; ip=ip+3) { + first = min (ranges[ip], ranges[ip+1]) + last = max (ranges[ip], ranges[ip+1]) + step = ranges[ip+2] + if (number >= first && number <= last) { + remainder = mod (number - first, step) + if (remainder == 0) + return (number) + if (number - remainder + step <= last) + next_number = number - remainder + step + } else if (first > number) + next_number = min (next_number, first) + } + + if (next_number == MAX_INT) + return (EOF) + else { + number = next_number + return (number) + } +end + + +# GET_PREVIOUS_NUMBER -- Given a list of ranges and the current file number, +# find and return the previous file number. Selection is done in such a way +# that list numbers are always returned in monotonically decreasing order, +# regardless of the order in which the ranges are given. Duplicate entries +# are ignored. EOF is returned at the end of the list. + +int procedure get_previous_number (ranges, number) + +int ranges[ARB] # Range array +int number # Both input and output parameter + +int ip, first, last, step, next_number, remainder + +begin + # If number-1 is anywhere in the list, that is the previous number, + # otherwise the previous number is the largest number in the list which + # is less than number-1. + + number = number - 1 + next_number = 0 + + for (ip=1; ranges[ip] != NULL; ip=ip+3) { + first = min (ranges[ip], ranges[ip+1]) + last = max (ranges[ip], ranges[ip+1]) + step = ranges[ip+2] + if (number >= first && number <= last) { + remainder = mod (number - first, step) + if (remainder == 0) + return (number) + if (number - remainder >= first) + next_number = number - remainder + } else if (last < number) { + remainder = mod (last - first, step) + if (remainder == 0) + next_number = max (next_number, last) + else if (last - remainder >= first) + next_number = max (next_number, last - remainder) + } + } + + if (next_number == 0) + return (EOF) + else { + number = next_number + return (number) + } +end + + +# IS_IN_RANGE -- Test number to see if it is in range. + +bool procedure is_in_range (ranges, number) + +int ranges[ARB] # Range array +int number # Number to be tested against ranges + +int ip, first, last, step + +begin + for (ip=1; ranges[ip] != NULL; ip=ip+3) { + first = min (ranges[ip], ranges[ip+1]) + last = max (ranges[ip], ranges[ip+1]) + step = ranges[ip+2] + if (number >= first && number <= last) + if (mod (number - first, step) == 0) + return (true) + } + + return (false) +end diff --git a/pkg/obsolete/fits/rfits.com b/pkg/obsolete/fits/rfits.com new file mode 100644 index 00000000..08f44c0e --- /dev/null +++ b/pkg/obsolete/fits/rfits.com @@ -0,0 +1,18 @@ + +# FITS reader common + +int len_record # Length of FITS records in bytes +int data_type # Output data type +real blank # Blank value +real fe # Maximum size in megabytes for scan mode + +# Option flags + +int make_image # Create an IRAF image +int long_header # Print a long header (FITS header cards) +int short_header # Print a short header (Title and size) +int scale # Scale the data +int old_name # Use old IRAF name? + +common /rfitscom/ len_record, data_type, blank, fe, make_image, long_header, + short_header, scale, old_name diff --git a/pkg/obsolete/fits/rfits.h b/pkg/obsolete/fits/rfits.h new file mode 100644 index 00000000..8afc5b0b --- /dev/null +++ b/pkg/obsolete/fits/rfits.h @@ -0,0 +1,80 @@ +# FITS Definitions + +# The FITS standard readable by the FITS reader using these definitions: +# +# 1. 8 bits / byte +# 2. ASCII character code +# 3. MII integer data format (i.e. 8 bit unsigned integers and 16 and 32 +# bit signed twos complement integers with most significant bytes first.) +# 4. IEEE 32 and 64 bit floating point format +# +# +# The following deviations from the FITS standard are allowed: +# +# 1. The number of FITS bytes per record is normally 2880 or up to 10 times +# 2880 bytes but may be arbitrarily specified by the user. + +# Define the bits per pixel, precision and byte order of the basic FITS types + +define FITS_RECORD 2880 # number of bytes in a standard FITS record + +define FITS_BYTE 8 # Bits in a FITS byte +define FITS_SHORT 16 # Bits in a FITS short +define FITS_LONG 32 # Bits in a FITS long +define FITS_REAL -32 # Bits in a FITS real * -1 +define FITS_DOUBLE -64 # Bits in a FITS double * -1 + +define FITSB_PREC 3 # Decimal digits of precision in a FITS byte +define FITSS_PREC 5 # Decimal digits of precision in a FITS short +define FITSL_PREC 10 # Decimal digits of precision in a FITS long + +define LSBF NO # Least significant byte first + +# Define the basic format of a FITS cardimage + +define LEN_CARD 80 # Length of FITS card in characters +define COL_VALUE 11 # Starting column for parameter values + + +# FITS standards not recognized currently by IRAF. +# +# 1. SIMPLE SIMPLE = 'F' not implemented, file skipped +# 2. GROUPS Group data not currently implemented, file skippped + + +# Values for the following quantities are stored in the structure below. + +define LEN_FITS (15 + SZ_FNAME + 1) + +define FITS_BSCALE Memd[P2D($1)] # FITS scaling parameter +define FITS_BZERO Memd[P2D($1+2)] # FITS zero parameter +define BLANK_VALUE Meml[P2L($1+4)] # Blank value +define BLANKS Memi[$1+5] # YES if blank keyword in header +define BITPIX Memi[$1+6] # Bits per pixel (Must be an MII type) +define SCALE Memi[$1+7] # Scale the data? +define SIMPLE Memi[$1+8] # Standard FITS format +define NRECORDS Memi[$1+9] # Number of FITS logical records +define IRAFNAME Memc[P2C($1+12)] # Old IRAF name + +# Mapping of additional IRAF header parameters + +define PIXTYPE IM_PIXTYPE($1) +define NBPIX IM_NBPIX($1) +define IRAFMAX IM_MAX($1) +define IRAFMIN IM_MIN($1) +define LIMTIME IM_LIMTIME($1) +define LEN_USERAREA 28800 + +# Mapping of FITS Keywords to IRAF image header + +define NAXIS IM_NDIM($1) +define NAXISN IM_LEN($1,$2) +define OBJECT IM_TITLE($1) +define HISTORY IM_HISTORY($1) +define UNKNOWN Memc[($1+IMU-1)*SZ_STRUCT+1] # All unrecognized keywords + # are stored here +# Miscellaneous definitions. + +define SZ_OBJECT SZ_IMTITLE +define SZ_HISTORY SZ_IMHIST +define SZ_FCTYPE SZ_CTYPE diff --git a/pkg/obsolete/fits/structure.hlp b/pkg/obsolete/fits/structure.hlp new file mode 100644 index 00000000..715ef185 --- /dev/null +++ b/pkg/obsolete/fits/structure.hlp @@ -0,0 +1,363 @@ +.help fits Apr84 "Program Structure" +.sh +RFITS Structure Chart + +.nf +t_rfits () +# Returns when file list is satisfied or if EOT is encountered +# Errors from called routines are trapped and printed as a warning. + + read_fits (fitsfile, iraffile) + # Returns OK or EOF + + read_header (fits_fd, fits, im) + # Returns OK or EOF + + decode_fits_card (fits, im, card) + # Returns YES or NO + + get_fits_string (card, str, maxchar) + + read_image (fits_fd, fits, im) + # Invokes error handler if EOF is encountered + + set_image_header (fits, im) + + set_coords (im) + # sets the coordinate transformations to a 1 to 1 + # mapping + + init_read_pixels (npix_record, bitpix, lsbf, spp_type) + # Returns OK + + put_imageline (im, bufptr, v, pixel_type) + # Outputs line to image + + read_pixels (fd, buffer, npix) + # Returns EOF or the number of pixels converted + + map_blanks (a, blanks, im) + + scale_line (line, bufptr, npix, bscale, bzero, + pixel_type) + # Converts the pixels to the output data type after + # applying bscale and bzero to the data + + change_line(line, bufptr, npix, pixel_type) + # Changes the FITS integers to the output pixel_type + # without scaling. +.fi + +.sh +RFITS Structure Summary + +.ls 4 t_rfits +The main procedure reads the control parameters. +The files to be read and converted are calculated from the specified source +and file list. A loop through +the files determines the specific input source names and output filenames +and calls READ_FITS for each conversion. +.ls read_fits +The input source is opened and the output image header file is created. +If only the FITS header is to be listed then a temporary image header file +is created. The FITS header is read and decoded into the IRAF image +header by READ_HEADER. If the image is to be read then MAKE_IMAGE is +called. Finally, all files are closed. If a temporary image header file +was created it is deleted. +.ls read_header +Some initialization is done on the IRAF header. +The FITS header cards are read one at a time. If EOF is encountered +then EOF is returned. If a long header listing has been specified then +the card is printed. The card is passed to DECODE_FITS_CARD. If +DECODE_FITS_CARD returns YES for the END card then the loop exits. If a +short header listing has bee specified then the title and image size +is printed. The routine returns OK if the header was successfully +interpreted or EOF if encountered. All other errors are returned +via the error handler. +.ls decode_fits_card +A series of STRMATCHes are made against the recognized FITS keywords. +If a match is found the possible actions are: +.ls +Convert a value to the IRAF image header. The conversions are defined in +fits.h +.le +.ls +Invoke an error condition +.le +.ls +Return a YES status if the keyword is END +.le + +Otherwise, the card is concatenated to the User Area of the IRAF image +header. If the keyword was not END then NO is returned. +.ls get_fits_string +The string field for a keyword with a string value is extracted. The +leading and trailing quotes are removed as well as trailing blanks. +The EOS is marked by either ', /, or the end of the card. +.le +.le +.le +.ls read_image +The FITS image pixels are converted to an IRAF image file. +The image file header is set. +The lines of the image are converted one at a time. +Each line is checked for blank values. +When all the image data has been read the number of blank pixels encounter +is printed (unless the value is zero). +.ls set_image_header +The pixel type for the IRAF image is set to the user specified type. +If no type has been specified then the type is determined from the number +of bits per pixel given in the FITS header. +.le +.ls set_coords +Sets the coordinate transformation parameters to a 1 to 1 transformation. +.le +.ls init_read_pixels +The pixel reading routine is initialized. The parameters are the number +of pixels per record, the number of bits per pixel which must be a +valid MII type, a byte order flag, and the SPP data type to be converted +to. In the FITS reader the byte order is specified to be most significant +byte first and the SPP data type is TY_LONG. +.le +.ls put_imageline +Put_imageline outputs a single line of the FITS image to the IRAF image. +.le +.ls read_pixels +The pixels are read into a record buffer. Data conversion is accomplished +with the MII routines since FITS format is the same as MII format. The +specified number of pixels is returned in the specified buffer. +.le +.ls map_blanks +Pixels having the blank value as given in the FITS header are added into +the bad pixel count in the image header. This routine will someday handle +mapping of bad pixels in a more detailed manner. +.le +.ls scale_line +The FITS integers from tape are converted to the output IRAF data type by +applying the FITS scaling parameters BSCALE and BZERO. +.le +.ls change_line +The FITS integers are converted directly to the output IRAF data type +without scaling (BSCALE = 1.0 and BZERO = 0.0). +.le +.le +.le + +.sh +WFITS Structure Chart + +.nf +t_wfits() +# Returns when the input file list is satisfied. +# Errors from called routines are trapped, an error message is issued and +# wfits terminates. + + wrt_fits (iraf_file, fits_file) + + data_limits (im) + + wrt_header (im, fits, fits_fd) + + set_bitbix (bitpix, pixtype, data_bitpix) + + iraf_type (pixtype, pixstring) + + set_scale (fits_bitpix, datamax, datamin, bscale, bzero) + + tape_limits (fits_bitpix, tapemax, tapemin) + + set_blank (fits_bitpix, blank, blankstr) + + init_wrt_pixels (npix_record, spp_type, mii_type) + + init_card_encode (im, fits) + # Returns YES + + card_encode (im, fits, card) + # Returns YES if valid FITS card + + get_standard_card (cardno, im, fits, axisno, + card + # Returns YES or NO + + get_option_card (im, fits, optiono, card) + # Returns YES or NO + + get_coord_card (im, coordno, coordaxis, card) + # Returns YES or NO + + get_history_card (im, histptr, card) + # Returns YES or NO + + get_end_card (card) + # Returns YES or NO + + wrt_pixels (fits_fd, card, len_card) + + wrt_last_record (fits_fd) + + wrt_image (im, fits, fits_fd) + + init_wrt_pixels (npix_record, spp_type, mii_type) + + get_image_line (im, bufptr, v, pixtype) + # Returns EOF or number of pixels in a line + + scale_line (bufptr, long_array, npix, bscale, bzero, + pixtype) + + long_line (bufptr, long_array, npix, pixtype) + + map_blanks (im, long_array, blank) + + wrt_pixels (fits_fd, long_array, npix) + + wrt_last_record (fits_fd) +.fi +.sh +WFITS Structure Summary + +.ls t_wfits +The main procedure reads the control parameters. The files to be read and +converted are calculated from the specified source and file list. A loop +through the files determines the specific input source names and output +file names and calls WRT_FITS for each file conversion. Write errors are trapped +and cause termination of the program. +.ls wrt_fits +The input source is opened. If the make_image switch is set the output +destination is opened. The IRAF image header parameters are encoded into +the FITS header and both header and pixels are written to the output +destination. +DATA_LIMITS is called if the autoscale switch is enabled and the IRAF image +data maximum and minimum values are unknown or the image has been modified +since they were last calculated. +If the make_image switch is turned off the FITS header is printed +on the standard output and a temporary output file is created. Finally +all the files are closed. If a temporary file was created it is deleted. +.ls data_limits +DATA_LIMITS calculates the minimum and maximum data values in an IRAF image. +The calculation is made only if these values are +undefined or the image has been modified since the last values were +calculated. +.le +.ls wrt_header +Some initialization is done on the FITS header. The appropriate FITS bitpix, +bzero and bscale factors, and the tape value for blank pixels are calculated +for each image. +The FITS header cards are encoded one at a time. If a long_header listing +has been specified then the FITS card is printed on the standard output. +If a short_header listing +is specified then the title and image size only are printed. Encoding terminates +when the FITS END keyword is encountered. Partial header records are filled +with blanks before being written to the output destination. +.ls set_bitpix +The value of the FITS bitpix is calculated. If the user given bitpix is +not a valid FITS bitpix, SET_BITPIX uses the precision of the IRAF image data +to set bitpix. +.le +.ls iraf_type +The IRAF datatype value is set to either INTEGER, FLOATING or COMPLEX. +.le +.ls set_scale +The bscale and bzero values are calculated from the IRAF minimum and maximum +data values and the FITS bitpix. +.ls tape_limits +The maximum and minimum FITS integer values are calculated from the FITS bitpix. +.le +.le +.ls set_blank +The FITS integer value for a blank pixel is calculated from the FITS bitpix. +.le +.ls init_wrt_pixels +The pixel writing routine is initialized. The parameters are the number of +pixels per record, the spp_type and the number of bits per pixel which +must be a valid mii type. For ASCII header card images the number of pixels +per record is normally 2880 and the bits per pixel is 8. The spp type is +always TY_CHAR. +.le +.ls init_card_encode +The card encoding procedure is initialized. The number of standard keyword, +optional keywords, coordinate transformation keywords, and history keywords +are calculated. +.le +.ls card_encode +An eighty character FITS format string is created for each permitted +FITS keyword. +.ls get_standard_card +The minimum required FITS header parameters, SIMPLE, BITPIX, NAXIS and NAXIS# +are encode into FITS cards. +.le +.ls get_option_card +A set of optional FITS parameters are encoded into FITS cards. +At present the permitted keywords are BSCALE, BZERO, BUNIT, BLANK +OBJECT, ORIGIN, DATE, IRAFMAX, IRAFMIN, IRAF-B/P, and IRAFTYPE. +The BLANK card is only encoded if the number of bad pixels in the +IRAF image header is nonzero. BUNIT and OBJECT cards are only encoded if +if the appropriate strings in the IRAF image header are defined. +.le +.ls get_coord_card +The coordinate transformation parameters are encoded into FITS header cards. +.le +.ls get_history_card +The IRAF history string is encoded into FITS header card(s). A maximum of +seven HISTORY cards are currently permitted by imio. +.le +.ls get_end_card +The FITS end card in encoded. +.le +.le +.ls wrt_pixels +The FITS card images are read into a record buffer. When the buffer is +full data conversion is accomplished using the mii routines since FITS +format is the same as mii format. After data conversion the record +buffer is written to the output destination. +.le +.ls wrt_last_record +The last partially filled header record is padded with blanks and written to +the output destination. +.le +.le +.ls wrt_image +The IRAF image pixels are converted to FITS image format. The lines of the +IRAF image are converted one at a time. Each line is scaled (if scaling is +enabled and appropriate) and the IRAF pixels are converted to long integers. +WRT_PIXELS is called to convert the integers to the appropriate FITS +output type using the MII routines. +.ls init_wrt_pixels +The pixel writing routine is initialized. The parameters are the number of +pixels per output record, the spp type and the number of FITS bits per pixel +which must be a valid mii type. The number of pixels per output record is +2880, 1440 or 720 for FITS bitpix of 8, 16 or 32 respectively. The spp type +is always TY_LONG. +.le +.ls get_image_line +A single IRAF image line is read into an internal buffer. +.le +.ls scale_line +The IRAF image line is scaled by the FITS BSCALE and +BZERO scaling factors and converted to long integers. +SCALE_LINE is called if the scale switch is set. +.le +.ls long_line +The IRAF image data values are converted directly to long integers. +LONG_LINE is called if scaling switch is turned off. +.le +.ls map_blanks +This function will eventually map IRAF blank pixels to the appropriate +FITS integer for blanks. Implementation of this function is will occur +after the imio mods. +.le +.ls wrt_pixels +The scaled IRAF image lines are read into a record buffer. When the buffer is +full data conversion is accomplished using the MII routines since FITS +format is the same as mii format. After data conversion the record +buffer is written to the output destination. +.le +.ls wrt_last_record +The last partially full data record is padded with zeros and written to the +output destination. +.le +.le +.le +.le +.endhelp diff --git a/pkg/obsolete/fits/t_rfits.x b/pkg/obsolete/fits/t_rfits.x new file mode 100644 index 00000000..be4449ac --- /dev/null +++ b/pkg/obsolete/fits/t_rfits.x @@ -0,0 +1,184 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fset.h> +include "rfits.h" + +define MAX_RANGES 100 # the maxium number of ranges +define NTYPES 7 # the number of image data types + +# RFITS -- Read FITS format data. Further documentation given in rfits.hlp + +procedure t_rfits() + +char infile[SZ_FNAME] # fits file +char file_list[SZ_LINE] # list of tape files +char outfile[SZ_FNAME] # IRAF file +char in_fname[SZ_FNAME] # input file name +char out_fname[SZ_FNAME] # output file name + +int len_inlist, len_outlist +int range[MAX_RANGES*3+1], file_number, offset, stat +pointer inlist, outlist + +bool clgetb() +char clgetc() +int rft_get_image_type(), clgeti(), mtfile(), strlen(), btoi(), fntlenb() +int rft_read_fitz(), decode_ranges(), get_next_number(), fntgfnb(), fstati() +int mtneedfileno(), fntrfnb() +pointer fntopnb() +real clgetr(), rft_fe() + +include "rfits.com" + +begin + # Set up the standard output to flush on a newline. + if (fstati (STDOUT, F_REDIR) == NO) + call fseti (STDOUT, F_FLUSHNL, YES) + + # Get RFITS parameters. + call clgstr ("fits_file", infile, SZ_FNAME) + long_header = btoi (clgetb ("long_header")) + short_header = btoi (clgetb ("short_header")) + len_record = FITS_RECORD + old_name = btoi (clgetb ("oldirafname")) + make_image = btoi (clgetb ("make_image")) + + # Open the input file list. + if (mtfile (infile) == YES) { + inlist = NULL + if (mtneedfileno (infile) == YES) + call clgstr ("file_list", file_list, SZ_LINE) + else + call strcpy ("1", file_list, SZ_LINE) + } else { + inlist = fntopnb (infile, NO) + len_inlist = fntlenb (inlist) + if (len_inlist > 0) { + call sprintf (file_list, SZ_LINE, "1-%d") + call pargi (len_inlist) + } else + call sprintf (file_list, SZ_LINE, "0") + } + + # Decode the ranges string. + if (decode_ranges (file_list, range, MAX_RANGES, len_inlist) == ERR) + call error (1, "T_RFITS: Illegal file number list") + + # Open the output file list. + if (make_image == YES) { + call clgstr ("iraf_file", outfile, SZ_FNAME) + if (outfile[1] == EOS) { + if (old_name == YES) + call mktemp ("tmp", outfile, SZ_FNAME) + else + call error (0, "T_RFITS: Undefined output file name") + } + outlist = fntopnb (outfile, NO) + len_outlist = fntlenb (outlist) + data_type = rft_get_image_type (clgetc ("datatype")) + scale = btoi (clgetb ("scale")) + blank = clgetr ("blank") + offset = clgeti ("offset") + } else { + outfile[1] = EOS + outlist = NULL + len_outlist = 1 + } + if ((len_outlist > 1) && (len_outlist != len_inlist)) + call error (0, + "T_RFITS: Output and input lists have different lengths") + + # Get the scan size parameter. + fe = rft_fe (infile) + + # Read successive FITS files, convert and write into a numbered + # succession of output IRAF files. + + file_number = 0 + while (get_next_number (range, file_number) != EOF) { + + # Get the input file name. + if (inlist != NULL) { + if (fntgfnb (inlist, in_fname, SZ_FNAME) == EOF) + call error (0, "T_RFITS: Error reading input file name") + } else { + if (mtneedfileno (infile) == YES) + call mtfname (infile, file_number, in_fname, SZ_FNAME) + else + call strcpy (infile, in_fname, SZ_FNAME) + } + + # Get the output file name. + if (outlist == NULL) { + out_fname[1] = EOS + } else if (len_inlist > len_outlist) { + if (fntrfnb (outlist, 1, out_fname, SZ_FNAME) == EOF) + call strcpy (outfile, out_fname, SZ_FNAME) + if (len_inlist > 1) { + call sprintf (out_fname[strlen(out_fname)+1], SZ_FNAME, + "%04d") + call pargi (file_number + offset) + } + } else if (fntgfnb (outlist, out_fname, SZ_FNAME) == EOF) + call error (0, "T_RFITS: Error reading output file name") + + # Convert FITS file to the output IRAF file. If EOT is reached + # then exit. If an error is detected then print a warning and + # continue with the next file. + + iferr (stat = rft_read_fitz (in_fname, out_fname)) + call erract (EA_FATAL) + if (stat == EOF) + break + } + + if (inlist != NULL) + call fntclsb (inlist) + if (outlist != NULL) + call fntclsb (outlist) +end + + +# RFT_GET_IMAGE_TYPE -- Convert a character to and IRAF image type. + +int procedure rft_get_image_type (c) + +char c + +int type_codes[NTYPES], i +string types "usilrdx" +int stridx() +data type_codes /TY_USHORT, TY_SHORT, TY_INT, TY_LONG, TY_REAL, + TY_DOUBLE, TY_COMPLEX/ +begin + i = stridx (c, types) + if (i == 0) + return (ERR) + else + return (type_codes[stridx(c,types)]) +end + + +# RFT_FE -- Fetch the maximum file size in MB for tape scanning mode. + +real procedure rft_fe (file) + +char file[ARB] # the input file name + +pointer gty +real fe +int mtfile(), gtygeti() +pointer mtcap() +errchk gtygeti() + +begin + if (mtfile (file) == NO) + return (0.0) + iferr (gty = mtcap (file)) + return (0.0) + iferr (fe = gtygeti (gty, "fe")) + fe = 0.0 + call gtyclose (gty) + return (fe) +end diff --git a/pkg/obsolete/fits/t_wfits.x b/pkg/obsolete/fits/t_wfits.x new file mode 100644 index 00000000..13cdd81f --- /dev/null +++ b/pkg/obsolete/fits/t_wfits.x @@ -0,0 +1,216 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <error.h> +include <fset.h> +include "wfits.h" + +# T_WFITS -- This procedure converts a series of IRAF image files to +# FITS image files. + +procedure t_wfits () + +char iraf_files[SZ_FNAME] # list of IRAF images +char fits_files[SZ_FNAME] # list of FITS files +bool newtape # new or used tape ? +char in_fname[SZ_FNAME] # input file name +char out_fname[SZ_FNAME] # output file name + +int imlist, flist, nimages, nfiles, file_number +bool clgetb() +double clgetd() +int imtopen(), imtlen (), wft_get_bitpix(), clgeti(), imtgetim() +int mtfile(), btoi(), fstati(), fntlenb(), fntgfnb(), mtneedfileno() +int wft_blkfac(), fntrfnb(), strlen() +pointer fntopnb() + +include "wfits.com" + +begin + # Flush on a newline if STDOUT has not been redirected. + if (fstati (STDOUT, F_REDIR) == NO) + call fseti (STDOUT, F_FLUSHNL, YES) + + # Open iraf_files template and determine number of files in list. + call clgstr ("iraf_files", iraf_files, SZ_FNAME) + imlist = imtopen (iraf_files) + nimages = imtlen (imlist) + + # Get the wfits parameters. + long_header = btoi (clgetb ("long_header")) + short_header = btoi (clgetb ("short_header")) + make_image = btoi (clgetb ("make_image")) + + # Get the FITS bits per pixel and the FITS logical record size. + bitpix = wft_get_bitpix (clgeti ("bitpix")) + len_record = FITS_RECORD + + # Get the scaling parameters. + scale = btoi (clgetb ("scale")) + if (scale == YES) { + if (clgetb ("autoscale")) + autoscale = YES + else { + bscale = clgetd ("bscale") + bzero = clgetd ("bzero") + autoscale = NO + } + } else { + autoscale = NO + bscale = 1.0d0 + bzero = 0.0d0 + } + + # Get the output file name and type (tape or disk). If no tape file + # number is given for output, the user is asked if the tape is blank + # or contains data. If the tape is blank output begins at BOT, + # otherwise at EOT. + + if (make_image == YES) { + call clgstr ("fits_files", fits_files, SZ_FNAME) + if (mtfile (fits_files) == YES) { + flist = NULL + if (mtneedfileno (fits_files) == YES) { + newtape = clgetb ("newtape") + if (newtape) + call mtfname (fits_files, 1, out_fname, SZ_FNAME) + else + call mtfname (fits_files, EOT, out_fname, SZ_FNAME) + } else { + call strcpy (fits_files, out_fname, SZ_FNAME) + newtape = false + } + } else { + flist = fntopnb (fits_files, NO) + nfiles = fntlenb (flist) + if ((nfiles > 1) && (nfiles != nimages)) + call error (0, + "T_WFITS: Input and output lists are not the same length") + } + } else { + fits_files[1] = EOS + flist = NULL + } + + # Get the fits file blocking factor. + blkfac = wft_blkfac (fits_files, clgeti ("blocking_factor")) + + # Loop through the list of input images files. + + file_number = 1 + while (imtgetim (imlist, in_fname, SZ_FNAME) != EOF) { + + # Print the id string. + if (long_header == YES || short_header == YES) { + call printf ("File %d: %s") + call pargi (file_number) + call pargstr (in_fname) + } + + # Get the output file name. If single file output to disk, use + # name fits_file. If multiple file output to disk, the file number + # is added to the output file name, if no output name list is + # supplied. If an output name list is supplied then the names + # are extracted one by one from that list. + + if (make_image == YES) { + if (mtfile (fits_files) == YES) { + if (file_number == 2) + call mtfname (out_fname, EOT, out_fname, SZ_FNAME) + } else if (nfiles > 1) { + if (fntgfnb (flist, out_fname, SZ_FNAME) == EOF) + call error (0, "Error reading output file name") + } else { + if (fntrfnb (flist, 1, out_fname, SZ_FNAME) == EOF) + call strcpy (fits_files, out_fname, SZ_FNAME) + if (nimages > 1) { + call sprintf (out_fname[strlen(out_fname)+1], + SZ_FNAME, "%04d") + call pargi (file_number) + } + } + } + + # Write each output file. + iferr (call wft_write_fitz (in_fname, out_fname)) { + call printf ("Error writing file: %s\n") + call pargstr (out_fname) + call erract (EA_WARN) + break + } else + file_number = file_number + 1 + } + + # Close up the input and output lists. + call clpcls (imlist) + if (flist != NULL) + call fntclsb (flist) +end + + +# WFT_GET_BITPIX -- This procedure fetches the user determined bitpix or ERR if +# the bitpix is not one of the permitted FITS types. + +int procedure wft_get_bitpix (bitpix) + +int bitpix + +begin + switch (bitpix) { + case FITS_BYTE, FITS_SHORT, FITS_LONG, FITS_REAL, FITS_DOUBLE: + return (bitpix) + default: + return (ERR) + } +end + + +# WFT_BLKFAC -- Get the fits tape blocking factor. + +int procedure wft_blkfac (file, ublkfac) + +char file[ARB] # the input file name +int ublkfac # the user supplied blocking factor + +int bs, fb, blkfac +pointer gty +int mtfile(), mtcap(), gtygeti() +errchk mtcap(), gtygeti() + +begin + # Return a blocking factor of 1 if the file is a disk file. + if (mtfile (file) == NO) + return (0) + + # Open the tapecap device entry for the given device, and get + # the device block size and default FITS blocking factor + # parameters. + + iferr (gty = mtcap (file)) + return (max (ublkfac,1)) + iferr (bs = gtygeti (gty, "bs")) { + call gtyclose (gty) + return (max (ublkfac,1)) + } + iferr (fb = max (gtygeti (gty, "fb"), 1)) + fb = 1 + + # Determine whether the device is a fixed or variable blocked + # device. Set the fits blocking factor to the value of the fb + # parameter if device is fixed block or if the user has + # requested the default blocking factor. Set the blocking factor + # to the user requested value if the device supports variable + # blocking factors. + + if (bs == 0) { + if (ublkfac <= 0) + blkfac = fb + else + blkfac = ublkfac + } else + blkfac = fb + + call gtyclose (gty) + + return (blkfac) +end diff --git a/pkg/obsolete/fits/wfits.com b/pkg/obsolete/fits/wfits.com new file mode 100644 index 00000000..4d2a58f8 --- /dev/null +++ b/pkg/obsolete/fits/wfits.com @@ -0,0 +1,15 @@ +# FITS common block + +double bscale # FITS scaling factor +double bzero # FITS offset factor +int bitpix # Output bits per pixel +int len_record # Record length in FITS bytes +int long_header # Print long header? +int short_header # Print short header? +int make_image # Make a FITS image? +int scale # Scale the data with bzero and bscale? +int autoscale # Allow program to calculate bscale and bzero? +int blkfac # FITS tape blocking factor + +common /wfitscom/ bscale, bzero, bitpix, len_record, long_header, short_header, + make_image, scale, autoscale, blkfac diff --git a/pkg/obsolete/fits/wfits.h b/pkg/obsolete/fits/wfits.h new file mode 100644 index 00000000..d2a67c34 --- /dev/null +++ b/pkg/obsolete/fits/wfits.h @@ -0,0 +1,113 @@ +# WFITS header file + +# The basic FITS data structure + +define LEN_FITS (44 + SZ_FNAME + 1) + +define BSCALE Memd[P2D($1)] # FITS bscale value +define BZERO Memd[P2D($1+2)] # FITS bzero value +define TAPEMAX Memd[P2D($1+4)] # IRAF tape max +define TAPEMIN Memd[P2D($1+6)] # IRAF tape min +define IRAFMAX Memr[P2R($1+8)] # IRAF image maximum +define IRAFMIN Memr[P2R($1+9)] # IRAF image minimum +define BLANK Meml[P2L($1+10)] # FITS blank value +define FITS_BITPIX Memi[$1+11] # FITS bits per pixel +define DATA_BITPIX Memi[$1+12] # Data bits per pixel +define SCALE Memi[$1+13] # Scale data? +define BLANK_STRING Memc[P2C($1+19)] # String containing FITS blank value +define TYPE_STRING Memc[P2C($1+31)] # String containing IRAF type +define IRAFNAME Memc[P2C($1+41)] # IRAF file name + + +# Define the FITS record size + +define FITS_RECORD 2880 # Size of standard FITS record (bytes) + +# Define the FITS data types + +define FITS_BYTE 8 # Number of bits in a FITS byte +define FITS_SHORT 16 # Number of bits in a FITS short +define FITS_LONG 32 # Number of bits in a FITS long +define FITS_REAL -32 # Number of bits in a FITS real * -1 +define FITS_DOUBLE -64 # Number of bits in a FITS double * -1 + +# Define the FITS precision in decimal digits + +define BYTE_PREC 3 # Precision of FITS byte +define SHORT_PREC 5 # Precision of FITS short +define LONG_PREC 10 # Precision of FITS long + +# Define the FITS blank data values + +define BYTE_BLANK 0.0d0 # Blank value for a FITS byte +define SHORT_BLANK -3.2768d4 # Blank value for a FITS short +define LONG_BLANK -2.147483648d9 # Blank value for a FITS long + +# Define the FITS integer max and min values + +define BYTE_MAX 2.55d2 # Max value for a FITS byte +define BYTE_MIN 1.0d0 # Min value for a FITS byte +define SHORT_MAX 3.2767d4 # Max value for a FITS short +define SHORT_MIN -3.2767d4 # Min value for a FITS short +define LONG_MAX 2.147483647d9 # Max value for a FITS long +define LONG_MIN -2.147483647d9 # Min value for a FITS long + +# Define the FITS card image parameters + +define LEN_CARD 80 # Length of FITS header card +define LEN_KEYWORD 8 # Length of FITS keyword +define LEN_NAXIS_KYWRD 5 # Length of the NAXIS keyword string +define COL_VALUE 11 # First column of value field + +# Mapping of FITS task keywords to IRAF image header keywords + +define NAXIS IM_NDIM($1) # Number of dimensions +define NAXISN IM_LEN($1, $2) # Length of each dimension +define OBJECT IM_TITLE($1) # Image title +define HISTORY IM_HISTORY($1) # History +define UNKNOWN Memc[($1+IMU-1)*SZ_STRUCT+1] # IRAF user area + +define PIXTYPE IM_PIXTYPE($1) # Image pixel type +define NBPIX IM_NBPIX($1) # Number of bad pixels +define LIMTIME IM_LIMTIME($1) # Last modify limits time +define MTIME IM_MTIME($1) # Last modify time +define CTIME IM_CTIME($1) # Create time + +define LEN_USERAREA 28800 # Default user area size + +# Set up a structure for the WFITS parameters + +# Define the required keywords + +define FIRST_CARD 1 # FITS simple parameter +define SECOND_CARD 2 # FITS bitpix parameter +define THIRD_CARD 3 # FITS naxis parameter + +# Define the optional FITS KEYWORD parameters + +define NOPTIONS 12 # Number of optional keywords + +define KEY_BSCALE 1 # FITS bscale parameter +define KEY_BZERO 2 # FITS bzero parameter +define KEY_BUNIT 3 # FITS physical units +define KEY_BLANK 4 # FITS value of blank pixel +define KEY_OBJECT 5 # FITS title string +define KEY_ORIGIN 6 # Origin of FITS tape +define KEY_DATE 7 # Date the tape was written +define KEY_IRAFNAME 8 # Root name of IRAF image +define KEY_IRAFMAX 9 # Maximum value of IRAF image +define KEY_IRAFMIN 10 # Minimum value of IRAF image +define KEY_IRAFBP 11 # Bits per pixel in IRAF image +define KEY_IRAFTYPE 12 # IRAF image data type + +define LEN_STRING 8 # Minimum length of a string parameter +define LEN_OBJECT 63 # Maximum length of string parameter +define LEN_ALIGN 18 # Maximum length for aligning parameter +define LEN_ORIGIN 9 # Length of origin string +define LEN_BLANK 11 # Length of the blank string +define NDEC_REAL 7 # Precision of real data +define NDEC_DOUBLE 11 # Precision of double precision data + +# Miscellaneous + +define CENTURY 1900 diff --git a/pkg/obsolete/fixcol.gx b/pkg/obsolete/fixcol.gx new file mode 100644 index 00000000..86e65688 --- /dev/null +++ b/pkg/obsolete/fixcol.gx @@ -0,0 +1,45 @@ +include <imhdr.h> +include <imset.h> + +$for (silrdx) + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcol$t (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2$t(), imps2$t() + +begin + c = imps2$t (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2$t (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovk$t (Mem$t[a + i - 1], Mem$t[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2$t (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovk$t (Mem$t[a + i - 1], Mem$t[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2$t (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2$t (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Mem$t[a + i - 1] + f2 = Mem$t[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Mem$t[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + +$endfor diff --git a/pkg/obsolete/fixcol.x b/pkg/obsolete/fixcol.x new file mode 100644 index 00000000..aa21a13a --- /dev/null +++ b/pkg/obsolete/fixcol.x @@ -0,0 +1,248 @@ +include <imhdr.h> +include <imset.h> + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcols (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2s(), imps2s() + +begin + c = imps2s (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2s (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovks (Mems[a + i - 1], Mems[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2s (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovks (Mems[a + i - 1], Mems[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2s (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2s (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Mems[a + i - 1] + f2 = Mems[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Mems[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcoli (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2i(), imps2i() + +begin + c = imps2i (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2i (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovki (Memi[a + i - 1], Memi[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2i (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovki (Memi[a + i - 1], Memi[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2i (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2i (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memi[a + i - 1] + f2 = Memi[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memi[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcoll (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2l(), imps2l() + +begin + c = imps2l (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2l (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkl (Meml[a + i - 1], Meml[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2l (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkl (Meml[a + i - 1], Meml[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2l (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2l (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Meml[a + i - 1] + f2 = Meml[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Meml[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcolr (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2r(), imps2r() + +begin + c = imps2r (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2r (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkr (Memr[a + i - 1], Memr[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2r (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkr (Memr[a + i - 1], Memr[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2r (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2r (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memr[a + i - 1] + f2 = Memr[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memr[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcold (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2d(), imps2d() + +begin + c = imps2d (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2d (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkd (Memd[a + i - 1], Memd[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2d (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkd (Memd[a + i - 1], Memd[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2d (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2d (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memd[a + i - 1] + f2 = Memd[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memd[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcolx (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2x(), imps2x() + +begin + c = imps2x (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2x (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkx (Memx[a + i - 1], Memx[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2x (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkx (Memx[a + i - 1], Memx[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2x (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2x (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memx[a + i - 1] + f2 = Memx[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memx[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end diff --git a/pkg/obsolete/fixline.gx b/pkg/obsolete/fixline.gx new file mode 100644 index 00000000..8a6c3672 --- /dev/null +++ b/pkg/obsolete/fixline.gx @@ -0,0 +1,50 @@ +include <imhdr.h> +include <imset.h> + +$for (silrdx) + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixline$t (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +$if (datatype == x) +complex f1, f2 +$else $if (datatype == d) +double f1, f2 +$else +real f1, f2 +$endif $endif +pointer a, b, c + +pointer imgs2$t(), imps2$t() + +begin + c = imps2$t (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2$t (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amov$t (Mem$t[a], Mem$t[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2$t (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amov$t (Mem$t[a], Mem$t[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2$t (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2$t (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsu$t (Mem$t[a], Mem$t[b], Mem$t[c+(i-1)*nx], nx, f1, f2) + } + } +end + +$endfor diff --git a/pkg/obsolete/fixline.x b/pkg/obsolete/fixline.x new file mode 100644 index 00000000..d11c031f --- /dev/null +++ b/pkg/obsolete/fixline.x @@ -0,0 +1,242 @@ +include <imhdr.h> +include <imset.h> + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlines (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2s(), imps2s() + +begin + c = imps2s (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2s (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovs (Mems[a], Mems[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2s (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovs (Mems[a], Mems[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2s (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2s (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsus (Mems[a], Mems[b], Mems[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinei (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2i(), imps2i() + +begin + c = imps2i (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2i (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovi (Memi[a], Memi[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2i (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovi (Memi[a], Memi[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2i (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2i (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsui (Memi[a], Memi[b], Memi[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinel (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2l(), imps2l() + +begin + c = imps2l (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2l (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovl (Meml[a], Meml[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2l (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovl (Meml[a], Meml[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2l (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2l (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsul (Meml[a], Meml[b], Meml[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixliner (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2r(), imps2r() + +begin + c = imps2r (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2r (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovr (Memr[a], Memr[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2r (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovr (Memr[a], Memr[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2r (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2r (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsur (Memr[a], Memr[b], Memr[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlined (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +double f1, f2 +pointer a, b, c + +pointer imgs2d(), imps2d() + +begin + c = imps2d (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2d (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovd (Memd[a], Memd[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2d (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovd (Memd[a], Memd[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2d (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2d (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsud (Memd[a], Memd[b], Memd[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinex (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +complex f1, f2 +pointer a, b, c + +pointer imgs2x(), imps2x() + +begin + c = imps2x (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2x (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovx (Memx[a], Memx[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2x (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovx (Memx[a], Memx[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2x (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2x (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsux (Memx[a], Memx[b], Memx[c+(i-1)*nx], nx, f1, f2) + } + } +end diff --git a/pkg/obsolete/generic/fixcol.x b/pkg/obsolete/generic/fixcol.x new file mode 100644 index 00000000..ef64694a --- /dev/null +++ b/pkg/obsolete/generic/fixcol.x @@ -0,0 +1,250 @@ +include <imhdr.h> +include <imset.h> + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcols (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2s(), imps2s() + +begin + c = imps2s (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2s (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovks (Mems[a + i - 1], Mems[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2s (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovks (Mems[a + i - 1], Mems[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2s (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2s (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Mems[a + i - 1] + f2 = Mems[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Mems[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcoli (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2i(), imps2i() + +begin + c = imps2i (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2i (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovki (Memi[a + i - 1], Memi[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2i (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovki (Memi[a + i - 1], Memi[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2i (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2i (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memi[a + i - 1] + f2 = Memi[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memi[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcoll (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2l(), imps2l() + +begin + c = imps2l (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2l (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkl (Meml[a + i - 1], Meml[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2l (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkl (Meml[a + i - 1], Meml[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2l (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2l (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Meml[a + i - 1] + f2 = Meml[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Meml[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcolr (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2r(), imps2r() + +begin + c = imps2r (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2r (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkr (Memr[a + i - 1], Memr[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2r (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkr (Memr[a + i - 1], Memr[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2r (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2r (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memr[a + i - 1] + f2 = Memr[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memr[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcold (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2d(), imps2d() + +begin + c = imps2d (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2d (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkd (Memd[a + i - 1], Memd[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2d (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkd (Memd[a + i - 1], Memd[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2d (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2d (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memd[a + i - 1] + f2 = Memd[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memd[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + + +# FIXCOL -- Linearly interpolate columns across a region. + +procedure fixcolx (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, j, nx, ny +real f1, f2, scale +pointer a, b, c +pointer imgs2x(), imps2x() + +begin + c = imps2x (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (x1 == 1) { + a = imgs2x (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny + call amovkx (Memx[a + i - 1], Memx[c + (i - 1) * nx], nx) + } else if (x2 == IM_LEN (image, 1)) { + a = imgs2x (image, x1 - 1, x1 - 1, y1, y2) + do i = 1, ny + call amovkx (Memx[a + i - 1], Memx[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2x (image, x1 - 1, x1 - 1, y1, y2) + b = imgs2x (image, x2 + 1, x2 + 1, y1, y2) + do i = 1, ny { + f1 = Memx[a + i - 1] + f2 = Memx[b + i - 1] + scale = (f2 - f1) / (nx + 1) + do j = 1, nx + Memx[c + (i - 1) * nx + j - 1] = j * scale + f1 + } + } +end + + diff --git a/pkg/obsolete/generic/fixline.x b/pkg/obsolete/generic/fixline.x new file mode 100644 index 00000000..86fcdcc0 --- /dev/null +++ b/pkg/obsolete/generic/fixline.x @@ -0,0 +1,244 @@ +include <imhdr.h> +include <imset.h> + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlines (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2s(), imps2s() + +begin + c = imps2s (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2s (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovs (Mems[a], Mems[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2s (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovs (Mems[a], Mems[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2s (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2s (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsus (Mems[a], Mems[b], Mems[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinei (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2i(), imps2i() + +begin + c = imps2i (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2i (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovi (Memi[a], Memi[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2i (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovi (Memi[a], Memi[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2i (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2i (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsui (Memi[a], Memi[b], Memi[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinel (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2l(), imps2l() + +begin + c = imps2l (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2l (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovl (Meml[a], Meml[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2l (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovl (Meml[a], Meml[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2l (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2l (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsul (Meml[a], Meml[b], Meml[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixliner (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +real f1, f2 +pointer a, b, c + +pointer imgs2r(), imps2r() + +begin + c = imps2r (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2r (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovr (Memr[a], Memr[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2r (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovr (Memr[a], Memr[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2r (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2r (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsur (Memr[a], Memr[b], Memr[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlined (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +double f1, f2 +pointer a, b, c + +pointer imgs2d(), imps2d() + +begin + c = imps2d (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2d (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovd (Memd[a], Memd[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2d (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovd (Memd[a], Memd[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2d (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2d (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsud (Memd[a], Memd[b], Memd[c+(i-1)*nx], nx, f1, f2) + } + } +end + + + +# FIXLINE -- Linearly interpolate lines across a region. + +procedure fixlinex (image, x1, x2, y1, y2) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed + +int i, nx, ny +complex f1, f2 +pointer a, b, c + +pointer imgs2x(), imps2x() + +begin + c = imps2x (image, x1, x2, y1, y2) + + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + if (y1 == 1) { + a = imgs2x (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny + call amovx (Memx[a], Memx[c + (i - 1) * nx], nx) + } else if (y2 == IM_LEN (image, 2)) { + a = imgs2x (image, x1, x2, y1 - 1, y1 - 1) + do i = 1, ny + call amovx (Memx[a], Memx[c + (i - 1) * nx], nx) + } else { + call imseti (image, IM_NBUFS, 2) + a = imgs2x (image, x1, x2, y1 - 1, y1 - 1) + b = imgs2x (image, x1, x2, y2 + 1, y2 + 1) + do i = 1, ny { + f2 = i / (ny + 1.) + f1 = 1 - f2 + call awsux (Memx[a], Memx[b], Memx[c+(i-1)*nx], nx, f1, f2) + } + } +end + + diff --git a/pkg/obsolete/generic/mkpkg b/pkg/obsolete/generic/mkpkg new file mode 100644 index 00000000..b38ee3df --- /dev/null +++ b/pkg/obsolete/generic/mkpkg @@ -0,0 +1,11 @@ +# Make generic routines. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + fixcol.x <imhdr.h> <imset.h> + fixline.x <imhdr.h> <imset.h> + ; diff --git a/pkg/obsolete/imcombine/generic/icaclip.x b/pkg/obsolete/imcombine/generic/icaclip.x new file mode 100644 index 00000000..2dd4d31e --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icaclip.x @@ -0,0 +1,2198 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Minimum number of images for this algorithm + + +# IC_AAVSIGCLIP -- Reject pixels using an average sigma about the average +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_aavsigclips (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, s1, r, one +data one /1.0/ +pointer sp, sums, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (sums, npts, TY_REAL) + call salloc (resid, nimages+1, TY_REAL) + + # Since the unweighted average is computed here possibly skip combining + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Compute the unweighted average with the high and low rejected and + # the poisson scaled average sigma. There must be at least three + # pixels at each point to define the average and contributions to + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + nin = n[1] + s = 0. + n2 = 0 + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) + next + + # Unweighted average with the high and low rejected + low = Mems[d[1]+k] + high = Mems[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mems[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Mems[dp1] + l = Memi[mp1] + s1 = max (one, (a + zeros[l]) / scales[l]) + s = s + (d1 - a) ** 2 / s1 + } + } else { + s1 = max (one, a) + do j = 1, n1 + s = s + (Mems[d[j]+k] - a) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the average and sum for later. + average[i] = a + Memr[sums+k] = sum + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + + # Reject pixels and compute the final average (if needed). + # There must be at least three pixels at each point for rejection. + # Iteratively scale the mean sigma and reject pixels + # Compact the data and keep track of the image IDs if needed. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (2, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mems[d[1]+k] + do j = 2, n1 + sum = sum + Mems[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + a = average[i] + sum = Memr[sums+k] + + repeat { + n2 = n1 + if (s > 0.) { + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Mems[dp1] + l = Memi[mp1] + s1 = s * sqrt (max (one, (a+zeros[l]) / scales[l])) + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + s1 = s * sqrt (max (one, a)) + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Mems[dp1] + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MAVSIGCLIP -- Reject pixels using an average sigma about the median +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_mavsigclips (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +pointer sp, resid, mp1, mp2 +real med, low, high, r, s, s1, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute the poisson scaled average sigma about the median. + # There must be at least three pixels at each point to define + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + s = 0. + n2 = 0 + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) { + if (n1 == 0) + median[i] = blank + else if (n1 == 1) + median[i] = Mems[d[1]+k] + else { + low = Mems[d[1]+k] + high = Mems[d[2]+k] + median[i] = (low + high) / 2. + } + next + } + + # Median + n3 = 1 + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mems[d[n3-1]+k] + high = Mems[d[n3]+k] + med = (low + high) / 2. + } else + med = Mems[d[n3]+k] + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + l = Memi[m[j]+k] + s1 = max (one, (med + zeros[l]) / scales[l]) + s = s + (Mems[d[j]+k] - med) ** 2 / s1 + } + } else { + s1 = max (one, med) + do j = 1, n1 + s = s + (Mems[d[j]+k] - med) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the median for later. + median[i] = med + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + else + return + + # Compute individual sigmas and iteratively clip. + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 < max (3, maxkeep+1)) + next + nl = 1 + nh = n1 + med = median[i] + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 >= max (MINCLIP, maxkeep+1) && s > 0.) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (med - Mems[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (Mems[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + s1 = s * sqrt (max (one, med)) + for (; nl <= n2; nl = nl + 1) { + r = (med - Mems[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mems[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mems[d[n3-1]+k] + high = Mems[d[n3]+k] + med = (low + high) / 2. + } else + med = Mems[d[n3]+k] + } else + med = blank + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mems[d[n3-1]+k] + high = Mems[d[n3]+k] + med = (low + high) / 2. + } else + med = Mems[d[n3]+k] + } else + med = blank + } + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mems[d[l]+k] = Mems[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mems[d[l]+k] = Mems[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_AAVSIGCLIP -- Reject pixels using an average sigma about the average +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_aavsigclipi (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, s1, r, one +data one /1.0/ +pointer sp, sums, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (sums, npts, TY_REAL) + call salloc (resid, nimages+1, TY_REAL) + + # Since the unweighted average is computed here possibly skip combining + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Compute the unweighted average with the high and low rejected and + # the poisson scaled average sigma. There must be at least three + # pixels at each point to define the average and contributions to + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + nin = n[1] + s = 0. + n2 = 0 + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) + next + + # Unweighted average with the high and low rejected + low = Memi[d[1]+k] + high = Memi[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memi[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memi[dp1] + l = Memi[mp1] + s1 = max (one, (a + zeros[l]) / scales[l]) + s = s + (d1 - a) ** 2 / s1 + } + } else { + s1 = max (one, a) + do j = 1, n1 + s = s + (Memi[d[j]+k] - a) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the average and sum for later. + average[i] = a + Memr[sums+k] = sum + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + + # Reject pixels and compute the final average (if needed). + # There must be at least three pixels at each point for rejection. + # Iteratively scale the mean sigma and reject pixels + # Compact the data and keep track of the image IDs if needed. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (2, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memi[d[1]+k] + do j = 2, n1 + sum = sum + Memi[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + a = average[i] + sum = Memr[sums+k] + + repeat { + n2 = n1 + if (s > 0.) { + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memi[dp1] + l = Memi[mp1] + s1 = s * sqrt (max (one, (a+zeros[l]) / scales[l])) + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + s1 = s * sqrt (max (one, a)) + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memi[dp1] + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MAVSIGCLIP -- Reject pixels using an average sigma about the median +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_mavsigclipi (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +pointer sp, resid, mp1, mp2 +real med, low, high, r, s, s1, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute the poisson scaled average sigma about the median. + # There must be at least three pixels at each point to define + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + s = 0. + n2 = 0 + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) { + if (n1 == 0) + median[i] = blank + else if (n1 == 1) + median[i] = Memi[d[1]+k] + else { + low = Memi[d[1]+k] + high = Memi[d[2]+k] + median[i] = (low + high) / 2. + } + next + } + + # Median + n3 = 1 + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memi[d[n3-1]+k] + high = Memi[d[n3]+k] + med = (low + high) / 2. + } else + med = Memi[d[n3]+k] + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + l = Memi[m[j]+k] + s1 = max (one, (med + zeros[l]) / scales[l]) + s = s + (Memi[d[j]+k] - med) ** 2 / s1 + } + } else { + s1 = max (one, med) + do j = 1, n1 + s = s + (Memi[d[j]+k] - med) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the median for later. + median[i] = med + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + else + return + + # Compute individual sigmas and iteratively clip. + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 < max (3, maxkeep+1)) + next + nl = 1 + nh = n1 + med = median[i] + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 >= max (MINCLIP, maxkeep+1) && s > 0.) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (med - Memi[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (Memi[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + s1 = s * sqrt (max (one, med)) + for (; nl <= n2; nl = nl + 1) { + r = (med - Memi[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memi[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memi[d[n3-1]+k] + high = Memi[d[n3]+k] + med = (low + high) / 2. + } else + med = Memi[d[n3]+k] + } else + med = blank + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memi[d[n3-1]+k] + high = Memi[d[n3]+k] + med = (low + high) / 2. + } else + med = Memi[d[n3]+k] + } else + med = blank + } + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memi[d[l]+k] = Memi[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memi[d[l]+k] = Memi[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_AAVSIGCLIP -- Reject pixels using an average sigma about the average +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_aavsigclipr (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, s1, r, one +data one /1.0/ +pointer sp, sums, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (sums, npts, TY_REAL) + call salloc (resid, nimages+1, TY_REAL) + + # Since the unweighted average is computed here possibly skip combining + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Compute the unweighted average with the high and low rejected and + # the poisson scaled average sigma. There must be at least three + # pixels at each point to define the average and contributions to + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + nin = n[1] + s = 0. + n2 = 0 + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) + next + + # Unweighted average with the high and low rejected + low = Memr[d[1]+k] + high = Memr[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memr[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memr[dp1] + l = Memi[mp1] + s1 = max (one, (a + zeros[l]) / scales[l]) + s = s + (d1 - a) ** 2 / s1 + } + } else { + s1 = max (one, a) + do j = 1, n1 + s = s + (Memr[d[j]+k] - a) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the average and sum for later. + average[i] = a + Memr[sums+k] = sum + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + + # Reject pixels and compute the final average (if needed). + # There must be at least three pixels at each point for rejection. + # Iteratively scale the mean sigma and reject pixels + # Compact the data and keep track of the image IDs if needed. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (2, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memr[d[1]+k] + do j = 2, n1 + sum = sum + Memr[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + a = average[i] + sum = Memr[sums+k] + + repeat { + n2 = n1 + if (s > 0.) { + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memr[dp1] + l = Memi[mp1] + s1 = s * sqrt (max (one, (a+zeros[l]) / scales[l])) + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + s1 = s * sqrt (max (one, a)) + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memr[dp1] + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MAVSIGCLIP -- Reject pixels using an average sigma about the median +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_mavsigclipr (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +pointer sp, resid, mp1, mp2 +real med, low, high, r, s, s1, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute the poisson scaled average sigma about the median. + # There must be at least three pixels at each point to define + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + s = 0. + n2 = 0 + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) { + if (n1 == 0) + median[i] = blank + else if (n1 == 1) + median[i] = Memr[d[1]+k] + else { + low = Memr[d[1]+k] + high = Memr[d[2]+k] + median[i] = (low + high) / 2. + } + next + } + + # Median + n3 = 1 + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memr[d[n3-1]+k] + high = Memr[d[n3]+k] + med = (low + high) / 2. + } else + med = Memr[d[n3]+k] + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + l = Memi[m[j]+k] + s1 = max (one, (med + zeros[l]) / scales[l]) + s = s + (Memr[d[j]+k] - med) ** 2 / s1 + } + } else { + s1 = max (one, med) + do j = 1, n1 + s = s + (Memr[d[j]+k] - med) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the median for later. + median[i] = med + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + else + return + + # Compute individual sigmas and iteratively clip. + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 < max (3, maxkeep+1)) + next + nl = 1 + nh = n1 + med = median[i] + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 >= max (MINCLIP, maxkeep+1) && s > 0.) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (med - Memr[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (Memr[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + s1 = s * sqrt (max (one, med)) + for (; nl <= n2; nl = nl + 1) { + r = (med - Memr[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memr[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memr[d[n3-1]+k] + high = Memr[d[n3]+k] + med = (low + high) / 2. + } else + med = Memr[d[n3]+k] + } else + med = blank + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memr[d[n3-1]+k] + high = Memr[d[n3]+k] + med = (low + high) / 2. + } else + med = Memr[d[n3]+k] + } else + med = blank + } + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memr[d[l]+k] = Memr[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memr[d[l]+k] = Memr[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_AAVSIGCLIP -- Reject pixels using an average sigma about the average +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_aavsigclipd (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +double average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +double d1, low, high, sum, a, s, s1, r, one +data one /1.0D0/ +pointer sp, sums, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (sums, npts, TY_REAL) + call salloc (resid, nimages+1, TY_REAL) + + # Since the unweighted average is computed here possibly skip combining + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Compute the unweighted average with the high and low rejected and + # the poisson scaled average sigma. There must be at least three + # pixels at each point to define the average and contributions to + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + nin = n[1] + s = 0. + n2 = 0 + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) + next + + # Unweighted average with the high and low rejected + low = Memd[d[1]+k] + high = Memd[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memd[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memd[dp1] + l = Memi[mp1] + s1 = max (one, (a + zeros[l]) / scales[l]) + s = s + (d1 - a) ** 2 / s1 + } + } else { + s1 = max (one, a) + do j = 1, n1 + s = s + (Memd[d[j]+k] - a) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the average and sum for later. + average[i] = a + Memr[sums+k] = sum + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + + # Reject pixels and compute the final average (if needed). + # There must be at least three pixels at each point for rejection. + # Iteratively scale the mean sigma and reject pixels + # Compact the data and keep track of the image IDs if needed. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (2, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memd[d[1]+k] + do j = 2, n1 + sum = sum + Memd[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + a = average[i] + sum = Memr[sums+k] + + repeat { + n2 = n1 + if (s > 0.) { + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Memd[dp1] + l = Memi[mp1] + s1 = s * sqrt (max (one, (a+zeros[l]) / scales[l])) + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + s1 = s * sqrt (max (one, a)) + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memd[dp1] + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MAVSIGCLIP -- Reject pixels using an average sigma about the median +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_mavsigclipd (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +double median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +pointer sp, resid, mp1, mp2 +double med, low, high, r, s, s1, one +data one /1.0D0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute the poisson scaled average sigma about the median. + # There must be at least three pixels at each point to define + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + s = 0. + n2 = 0 + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) { + if (n1 == 0) + median[i] = blank + else if (n1 == 1) + median[i] = Memd[d[1]+k] + else { + low = Memd[d[1]+k] + high = Memd[d[2]+k] + median[i] = (low + high) / 2. + } + next + } + + # Median + n3 = 1 + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memd[d[n3-1]+k] + high = Memd[d[n3]+k] + med = (low + high) / 2. + } else + med = Memd[d[n3]+k] + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + l = Memi[m[j]+k] + s1 = max (one, (med + zeros[l]) / scales[l]) + s = s + (Memd[d[j]+k] - med) ** 2 / s1 + } + } else { + s1 = max (one, med) + do j = 1, n1 + s = s + (Memd[d[j]+k] - med) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the median for later. + median[i] = med + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + else + return + + # Compute individual sigmas and iteratively clip. + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 < max (3, maxkeep+1)) + next + nl = 1 + nh = n1 + med = median[i] + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 >= max (MINCLIP, maxkeep+1) && s > 0.) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (med - Memd[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (Memd[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + s1 = s * sqrt (max (one, med)) + for (; nl <= n2; nl = nl + 1) { + r = (med - Memd[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memd[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memd[d[n3-1]+k] + high = Memd[d[n3]+k] + med = (low + high) / 2. + } else + med = Memd[d[n3]+k] + } else + med = blank + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Memd[d[n3-1]+k] + high = Memd[d[n3]+k] + med = (low + high) / 2. + } else + med = Memd[d[n3]+k] + } else + med = blank + } + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memd[d[l]+k] = Memd[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memd[d[l]+k] = Memd[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/generic/icaverage.x b/pkg/obsolete/imcombine/generic/icaverage.x new file mode 100644 index 00000000..a2f6498d --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icaverage.x @@ -0,0 +1,337 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + + +# IC_AVERAGE -- Compute the average image line. +# Options include a weight average. + +procedure ic_averages (d, m, n, wts, npts, doblank, average) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +int doblank # Set blank values? +real average[npts] # Average (returned) + +int i, j, k +real sumwt, wt +real sum + +include "../icombine.com" + +begin + # If no data has been excluded do the average without checking the + # number of points and using the fact that the weights are normalized. + # If all the data has been excluded set the average to the blank value + # if requested. + + if (dflag == D_ALL) { + if (dowts) { + do i = 1, npts { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Mems[d[1]+k] * wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Mems[d[j]+k] * wt + } + average[i] = sum + } + } else { + do i = 1, npts { + k = i - 1 + sum = Mems[d[1]+k] + do j = 2, n[i] + sum = sum + Mems[d[j]+k] + average[i] = sum / n[i] + } + } + } else if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + average[i] = blank + } + } else { + if (dowts) { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Mems[d[1]+k] * wt + sumwt = wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Mems[d[j]+k] * wt + sumwt = sumwt + wt + } + average[i] = sum / sumwt + } else if (doblank == YES) + average[i] = blank + } + } else { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + sum = Mems[d[1]+k] + do j = 2, n[i] + sum = sum + Mems[d[j]+k] + average[i] = sum / n[i] + } else if (doblank == YES) + average[i] = blank + } + } + } +end + +# IC_AVERAGE -- Compute the average image line. +# Options include a weight average. + +procedure ic_averagei (d, m, n, wts, npts, doblank, average) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +int doblank # Set blank values? +real average[npts] # Average (returned) + +int i, j, k +real sumwt, wt +real sum + +include "../icombine.com" + +begin + # If no data has been excluded do the average without checking the + # number of points and using the fact that the weights are normalized. + # If all the data has been excluded set the average to the blank value + # if requested. + + if (dflag == D_ALL) { + if (dowts) { + do i = 1, npts { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memi[d[1]+k] * wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memi[d[j]+k] * wt + } + average[i] = sum + } + } else { + do i = 1, npts { + k = i - 1 + sum = Memi[d[1]+k] + do j = 2, n[i] + sum = sum + Memi[d[j]+k] + average[i] = sum / n[i] + } + } + } else if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + average[i] = blank + } + } else { + if (dowts) { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memi[d[1]+k] * wt + sumwt = wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memi[d[j]+k] * wt + sumwt = sumwt + wt + } + average[i] = sum / sumwt + } else if (doblank == YES) + average[i] = blank + } + } else { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + sum = Memi[d[1]+k] + do j = 2, n[i] + sum = sum + Memi[d[j]+k] + average[i] = sum / n[i] + } else if (doblank == YES) + average[i] = blank + } + } + } +end + +# IC_AVERAGE -- Compute the average image line. +# Options include a weight average. + +procedure ic_averager (d, m, n, wts, npts, doblank, average) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +int doblank # Set blank values? +real average[npts] # Average (returned) + +int i, j, k +real sumwt, wt +real sum + +include "../icombine.com" + +begin + # If no data has been excluded do the average without checking the + # number of points and using the fact that the weights are normalized. + # If all the data has been excluded set the average to the blank value + # if requested. + + if (dflag == D_ALL) { + if (dowts) { + do i = 1, npts { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memr[d[1]+k] * wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memr[d[j]+k] * wt + } + average[i] = sum + } + } else { + do i = 1, npts { + k = i - 1 + sum = Memr[d[1]+k] + do j = 2, n[i] + sum = sum + Memr[d[j]+k] + average[i] = sum / n[i] + } + } + } else if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + average[i] = blank + } + } else { + if (dowts) { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memr[d[1]+k] * wt + sumwt = wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memr[d[j]+k] * wt + sumwt = sumwt + wt + } + average[i] = sum / sumwt + } else if (doblank == YES) + average[i] = blank + } + } else { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + sum = Memr[d[1]+k] + do j = 2, n[i] + sum = sum + Memr[d[j]+k] + average[i] = sum / n[i] + } else if (doblank == YES) + average[i] = blank + } + } + } +end + +# IC_AVERAGE -- Compute the average image line. +# Options include a weight average. + +procedure ic_averaged (d, m, n, wts, npts, doblank, average) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +int doblank # Set blank values? +double average[npts] # Average (returned) + +int i, j, k +real sumwt, wt +double sum + +include "../icombine.com" + +begin + # If no data has been excluded do the average without checking the + # number of points and using the fact that the weights are normalized. + # If all the data has been excluded set the average to the blank value + # if requested. + + if (dflag == D_ALL) { + if (dowts) { + do i = 1, npts { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memd[d[1]+k] * wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memd[d[j]+k] * wt + } + average[i] = sum + } + } else { + do i = 1, npts { + k = i - 1 + sum = Memd[d[1]+k] + do j = 2, n[i] + sum = sum + Memd[d[j]+k] + average[i] = sum / n[i] + } + } + } else if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + average[i] = blank + } + } else { + if (dowts) { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Memd[d[1]+k] * wt + sumwt = wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Memd[d[j]+k] * wt + sumwt = sumwt + wt + } + average[i] = sum / sumwt + } else if (doblank == YES) + average[i] = blank + } + } else { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + sum = Memd[d[1]+k] + do j = 2, n[i] + sum = sum + Memd[d[j]+k] + average[i] = sum / n[i] + } else if (doblank == YES) + average[i] = blank + } + } + } +end diff --git a/pkg/obsolete/imcombine/generic/iccclip.x b/pkg/obsolete/imcombine/generic/iccclip.x new file mode 100644 index 00000000..bf655477 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/iccclip.x @@ -0,0 +1,1790 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 2 # Mininum number of images for algorithm + + +# IC_ACCDCLIP -- Reject pixels using CCD noise parameters about the average + +procedure ic_accdclips (d, m, n, scales, zeros, nm, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model parameters +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, zero +data zero /0.0/ +pointer sp, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are no pixels go on to the combining. Since the unweighted + # average is computed here possibly skip the combining later. + + # There must be at least max (1, nkeep) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } else if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # There must be at least two pixels for rejection. The initial + # average is the low/high rejected average except in the case of + # just two pixels. The rejections are iterated and the average + # is recomputed. Corrections for scaling may be performed. + # Depending on other flags the image IDs may also need to be adjusted. + + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (MINCLIP-1, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mems[d[1]+k] + do j = 2, n1 + sum = sum + Mems[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + repeat { + if (n1 == 2) { + sum = Mems[d[1]+k] + sum = sum + Mems[d[2]+k] + a = sum / 2 + } else { + low = Mems[d[1]+k] + high = Mems[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mems[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + } + n2 = n1 + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + l = Memi[mp1] + s = scales[l] + d1 = max (zero, s * (a + zeros[l])) + s = sqrt (nm[1,l] + d1/nm[2,l] + (d1*nm[3,l])**2) / s + + d1 = Mems[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + if (!keepids) { + s = max (zero, a) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (j=1; j<=n1; j=j+1) { + if (keepids) { + l = Memi[m[j]+k] + s = max (zero, a) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + dp1 = d[j] + k + d1 = Mems[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + } + + n[i] = n1 + if (!docombine) + if (n1 > 0) + average[i] = sum / n1 + else + average[i] = blank + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_CCDCLIP -- Reject pixels using CCD noise parameters about the median + +procedure ic_mccdclips (d, m, n, scales, zeros, nm, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, mp1, mp2 +real med, zero +data zero /0.0/ + +include "../icombine.com" + +begin + # There must be at least max (MINCLIP, nkeep+1) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) { + med = Mems[d[n3-1]+k] + med = (med + Mems[d[n3]+k]) / 2. + } else + med = Mems[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (med - Mems[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (Mems[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + if (!keepids) { + s = max (zero, med) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (; nl <= n2; nl = nl + 1) { + if (keepids) { + l = Memi[m[nl]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (med - Mems[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + if (keepids) { + l = Memi[m[nh]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (Mems[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mems[d[l]+k] = Mems[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mems[d[l]+k] = Mems[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ACCDCLIP -- Reject pixels using CCD noise parameters about the average + +procedure ic_accdclipi (d, m, n, scales, zeros, nm, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model parameters +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, zero +data zero /0.0/ +pointer sp, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are no pixels go on to the combining. Since the unweighted + # average is computed here possibly skip the combining later. + + # There must be at least max (1, nkeep) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } else if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # There must be at least two pixels for rejection. The initial + # average is the low/high rejected average except in the case of + # just two pixels. The rejections are iterated and the average + # is recomputed. Corrections for scaling may be performed. + # Depending on other flags the image IDs may also need to be adjusted. + + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (MINCLIP-1, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memi[d[1]+k] + do j = 2, n1 + sum = sum + Memi[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + repeat { + if (n1 == 2) { + sum = Memi[d[1]+k] + sum = sum + Memi[d[2]+k] + a = sum / 2 + } else { + low = Memi[d[1]+k] + high = Memi[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memi[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + } + n2 = n1 + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + l = Memi[mp1] + s = scales[l] + d1 = max (zero, s * (a + zeros[l])) + s = sqrt (nm[1,l] + d1/nm[2,l] + (d1*nm[3,l])**2) / s + + d1 = Memi[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + if (!keepids) { + s = max (zero, a) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (j=1; j<=n1; j=j+1) { + if (keepids) { + l = Memi[m[j]+k] + s = max (zero, a) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + dp1 = d[j] + k + d1 = Memi[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + } + + n[i] = n1 + if (!docombine) + if (n1 > 0) + average[i] = sum / n1 + else + average[i] = blank + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_CCDCLIP -- Reject pixels using CCD noise parameters about the median + +procedure ic_mccdclipi (d, m, n, scales, zeros, nm, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, mp1, mp2 +real med, zero +data zero /0.0/ + +include "../icombine.com" + +begin + # There must be at least max (MINCLIP, nkeep+1) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) { + med = Memi[d[n3-1]+k] + med = (med + Memi[d[n3]+k]) / 2. + } else + med = Memi[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (med - Memi[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (Memi[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + if (!keepids) { + s = max (zero, med) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (; nl <= n2; nl = nl + 1) { + if (keepids) { + l = Memi[m[nl]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (med - Memi[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + if (keepids) { + l = Memi[m[nh]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (Memi[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memi[d[l]+k] = Memi[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memi[d[l]+k] = Memi[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ACCDCLIP -- Reject pixels using CCD noise parameters about the average + +procedure ic_accdclipr (d, m, n, scales, zeros, nm, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model parameters +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, zero +data zero /0.0/ +pointer sp, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are no pixels go on to the combining. Since the unweighted + # average is computed here possibly skip the combining later. + + # There must be at least max (1, nkeep) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } else if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # There must be at least two pixels for rejection. The initial + # average is the low/high rejected average except in the case of + # just two pixels. The rejections are iterated and the average + # is recomputed. Corrections for scaling may be performed. + # Depending on other flags the image IDs may also need to be adjusted. + + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (MINCLIP-1, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memr[d[1]+k] + do j = 2, n1 + sum = sum + Memr[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + repeat { + if (n1 == 2) { + sum = Memr[d[1]+k] + sum = sum + Memr[d[2]+k] + a = sum / 2 + } else { + low = Memr[d[1]+k] + high = Memr[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memr[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + } + n2 = n1 + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + l = Memi[mp1] + s = scales[l] + d1 = max (zero, s * (a + zeros[l])) + s = sqrt (nm[1,l] + d1/nm[2,l] + (d1*nm[3,l])**2) / s + + d1 = Memr[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + if (!keepids) { + s = max (zero, a) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (j=1; j<=n1; j=j+1) { + if (keepids) { + l = Memi[m[j]+k] + s = max (zero, a) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + dp1 = d[j] + k + d1 = Memr[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + } + + n[i] = n1 + if (!docombine) + if (n1 > 0) + average[i] = sum / n1 + else + average[i] = blank + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_CCDCLIP -- Reject pixels using CCD noise parameters about the median + +procedure ic_mccdclipr (d, m, n, scales, zeros, nm, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, mp1, mp2 +real med, zero +data zero /0.0/ + +include "../icombine.com" + +begin + # There must be at least max (MINCLIP, nkeep+1) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) { + med = Memr[d[n3-1]+k] + med = (med + Memr[d[n3]+k]) / 2. + } else + med = Memr[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (med - Memr[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (Memr[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + if (!keepids) { + s = max (zero, med) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (; nl <= n2; nl = nl + 1) { + if (keepids) { + l = Memi[m[nl]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (med - Memr[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + if (keepids) { + l = Memi[m[nh]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (Memr[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memr[d[l]+k] = Memr[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memr[d[l]+k] = Memr[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ACCDCLIP -- Reject pixels using CCD noise parameters about the average + +procedure ic_accdclipd (d, m, n, scales, zeros, nm, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model parameters +int nimages # Number of images +int npts # Number of output points per line +double average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +double d1, low, high, sum, a, s, r, zero +data zero /0.0D0/ +pointer sp, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are no pixels go on to the combining. Since the unweighted + # average is computed here possibly skip the combining later. + + # There must be at least max (1, nkeep) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } else if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # There must be at least two pixels for rejection. The initial + # average is the low/high rejected average except in the case of + # just two pixels. The rejections are iterated and the average + # is recomputed. Corrections for scaling may be performed. + # Depending on other flags the image IDs may also need to be adjusted. + + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (MINCLIP-1, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memd[d[1]+k] + do j = 2, n1 + sum = sum + Memd[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + repeat { + if (n1 == 2) { + sum = Memd[d[1]+k] + sum = sum + Memd[d[2]+k] + a = sum / 2 + } else { + low = Memd[d[1]+k] + high = Memd[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memd[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + } + n2 = n1 + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + l = Memi[mp1] + s = scales[l] + d1 = max (zero, s * (a + zeros[l])) + s = sqrt (nm[1,l] + d1/nm[2,l] + (d1*nm[3,l])**2) / s + + d1 = Memd[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + if (!keepids) { + s = max (zero, a) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (j=1; j<=n1; j=j+1) { + if (keepids) { + l = Memi[m[j]+k] + s = max (zero, a) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + dp1 = d[j] + k + d1 = Memd[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + } + + n[i] = n1 + if (!docombine) + if (n1 > 0) + average[i] = sum / n1 + else + average[i] = blank + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_CCDCLIP -- Reject pixels using CCD noise parameters about the median + +procedure ic_mccdclipd (d, m, n, scales, zeros, nm, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model +int nimages # Number of images +int npts # Number of output points per line +double median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, mp1, mp2 +double med, zero +data zero /0.0D0/ + +include "../icombine.com" + +begin + # There must be at least max (MINCLIP, nkeep+1) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) { + med = Memd[d[n3-1]+k] + med = (med + Memd[d[n3]+k]) / 2. + } else + med = Memd[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (med - Memd[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (Memd[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + if (!keepids) { + s = max (zero, med) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (; nl <= n2; nl = nl + 1) { + if (keepids) { + l = Memi[m[nl]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (med - Memd[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + if (keepids) { + l = Memi[m[nh]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (Memd[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memd[d[l]+k] = Memd[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memd[d[l]+k] = Memd[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/generic/icgdata.x b/pkg/obsolete/imcombine/generic/icgdata.x new file mode 100644 index 00000000..264acc34 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icgdata.x @@ -0,0 +1,918 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <mach.h> +include "../icombine.h" + + +# IC_GDATA -- Get line of image and mask data and apply threshold and scaling. +# Entirely empty lines are excluded. The data are compacted within the +# input data buffers. If it is required, the connection to the original +# image index is kept in the returned m data pointers. + +procedure ic_gdatas (in, out, dbuf, d, id, n, m, lflag, offsets, scales, + zeros, nimages, npts, v1, v2) + +pointer in[nimages] # Input images +pointer out[3] # Output images +pointer dbuf[nimages] # Data buffers +pointer d[nimages] # Data pointers +pointer id[nimages] # ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Empty mask flags +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +int nimages # Number of input images +int npts # NUmber of output points per line +long v1[ARB], v2[ARB] # Line vectors + +int i, j, k, l, ndim, nused +real a, b +pointer buf, dp, ip, mp, imgnls() + +include "../icombine.com" + +begin + # Get masks and return if there is no data + call ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + if (dflag == D_NONE) { + call aclri (n, npts) + return + } + + # Get data and fill data buffers. Correct for offsets if needed. + ndim = IM_NDIM(out[1]) + do i = 1, nimages { + if (lflag[i] == D_NONE) + next + if (dbuf[i] == NULL) { + call amovl (v1, v2, IM_MAXDIM) + if (project) + v2[ndim+1] = i + j = imgnls (in[i], d[i], v2) + } else { + v2[1] = v1[1] + do j = 2, ndim + v2[j] = v1[j] - offsets[i,j] + if (project) + v2[ndim+1] = i + j = imgnls (in[i], buf, v2) + call amovs (Mems[buf], Mems[dbuf[i]+offsets[i,1]], + IM_LEN(in[i],1)) + d[i] = dbuf[i] + } + } + + # Apply threshold if needed + if (dothresh) { + do i = 1, nimages { + dp = d[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + a = Mems[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + lflag[i] = D_MIX + dflag = D_MIX + } + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + a = Mems[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + dflag = D_MIX + } + } + dp = dp + 1 + mp = mp + 1 + } + } + + # Check for completely empty lines + if (lflag[i] == D_MIX) { + lflag[i] = D_NONE + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + lflag[i] = D_MIX + break + } + mp = mp + 1 + } + } + } + } + + # Apply scaling (avoiding masked pixels which might overflow?) + if (doscale) { + if (dflag == D_ALL) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + do j = 1, npts { + Mems[dp] = Mems[dp] / a + b + dp = dp + 1 + } + } + } else if (dflag == D_MIX) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + Mems[dp] = Mems[dp] / a + b + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) + Mems[dp] = Mems[dp] / a + b + dp = dp + 1 + mp = mp + 1 + } + } + } + } + } + + # Sort pointers to exclude unused images. + # Use the lflag array to keep track of the image index. + + if (dflag == D_ALL) + nused = nimages + else { + nused = 0 + do i = 1, nimages + if (lflag[i] != D_NONE) { + nused = nused + 1 + d[nused] = d[i] + m[nused] = m[i] + lflag[nused] = i + } + if (nused == 0) + dflag = D_NONE + } + + # Compact data to remove bad pixels + # Keep track of the image indices if needed + # If growing mark the end of the included image indices with zero + + if (dflag == D_ALL) { + call amovki (nused, n, npts) + if (keepids) + do i = 1, nimages + call amovki (i, Memi[id[i]], npts) + } else if (dflag == D_NONE) + call aclri (n, npts) + else { + call aclri (n, npts) + if (keepids) { + do i = 1, nused { + l = lflag[i] + dp = d[i] + ip = id[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) { + Mems[d[k]+j-1] = Mems[dp] + Memi[id[k]+j-1] = l + } else + Memi[ip] = l + } + dp = dp + 1 + ip = ip + 1 + mp = mp + 1 + } + } + if (grow >= 1.) { + do j = 1, npts { + do i = n[j]+1, nimages + Memi[id[i]+j-1] = 0 + } + } + } else { + do i = 1, nused { + dp = d[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) + Mems[d[k]+j-1] = Mems[dp] + } + dp = dp + 1 + mp = mp + 1 + } + } + } + } + + # Sort the pixels and IDs if needed + if (mclip) { + call malloc (dp, nimages, TY_SHORT) + if (keepids) { + call malloc (ip, nimages, TY_INT) + call ic_2sorts (d, Mems[dp], id, Memi[ip], n, npts) + call mfree (ip, TY_INT) + } else + call ic_sorts (d, Mems[dp], n, npts) + call mfree (dp, TY_SHORT) + } +end + +# IC_GDATA -- Get line of image and mask data and apply threshold and scaling. +# Entirely empty lines are excluded. The data are compacted within the +# input data buffers. If it is required, the connection to the original +# image index is kept in the returned m data pointers. + +procedure ic_gdatai (in, out, dbuf, d, id, n, m, lflag, offsets, scales, + zeros, nimages, npts, v1, v2) + +pointer in[nimages] # Input images +pointer out[3] # Output images +pointer dbuf[nimages] # Data buffers +pointer d[nimages] # Data pointers +pointer id[nimages] # ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Empty mask flags +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +int nimages # Number of input images +int npts # NUmber of output points per line +long v1[ARB], v2[ARB] # Line vectors + +int i, j, k, l, ndim, nused +real a, b +pointer buf, dp, ip, mp, imgnli() + +include "../icombine.com" + +begin + # Get masks and return if there is no data + call ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + if (dflag == D_NONE) { + call aclri (n, npts) + return + } + + # Get data and fill data buffers. Correct for offsets if needed. + ndim = IM_NDIM(out[1]) + do i = 1, nimages { + if (lflag[i] == D_NONE) + next + if (dbuf[i] == NULL) { + call amovl (v1, v2, IM_MAXDIM) + if (project) + v2[ndim+1] = i + j = imgnli (in[i], d[i], v2) + } else { + v2[1] = v1[1] + do j = 2, ndim + v2[j] = v1[j] - offsets[i,j] + if (project) + v2[ndim+1] = i + j = imgnli (in[i], buf, v2) + call amovi (Memi[buf], Memi[dbuf[i]+offsets[i,1]], + IM_LEN(in[i],1)) + d[i] = dbuf[i] + } + } + + # Apply threshold if needed + if (dothresh) { + do i = 1, nimages { + dp = d[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + a = Memi[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + lflag[i] = D_MIX + dflag = D_MIX + } + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + a = Memi[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + dflag = D_MIX + } + } + dp = dp + 1 + mp = mp + 1 + } + } + + # Check for completely empty lines + if (lflag[i] == D_MIX) { + lflag[i] = D_NONE + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + lflag[i] = D_MIX + break + } + mp = mp + 1 + } + } + } + } + + # Apply scaling (avoiding masked pixels which might overflow?) + if (doscale) { + if (dflag == D_ALL) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + do j = 1, npts { + Memi[dp] = Memi[dp] / a + b + dp = dp + 1 + } + } + } else if (dflag == D_MIX) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + Memi[dp] = Memi[dp] / a + b + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) + Memi[dp] = Memi[dp] / a + b + dp = dp + 1 + mp = mp + 1 + } + } + } + } + } + + # Sort pointers to exclude unused images. + # Use the lflag array to keep track of the image index. + + if (dflag == D_ALL) + nused = nimages + else { + nused = 0 + do i = 1, nimages + if (lflag[i] != D_NONE) { + nused = nused + 1 + d[nused] = d[i] + m[nused] = m[i] + lflag[nused] = i + } + if (nused == 0) + dflag = D_NONE + } + + # Compact data to remove bad pixels + # Keep track of the image indices if needed + # If growing mark the end of the included image indices with zero + + if (dflag == D_ALL) { + call amovki (nused, n, npts) + if (keepids) + do i = 1, nimages + call amovki (i, Memi[id[i]], npts) + } else if (dflag == D_NONE) + call aclri (n, npts) + else { + call aclri (n, npts) + if (keepids) { + do i = 1, nused { + l = lflag[i] + dp = d[i] + ip = id[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) { + Memi[d[k]+j-1] = Memi[dp] + Memi[id[k]+j-1] = l + } else + Memi[ip] = l + } + dp = dp + 1 + ip = ip + 1 + mp = mp + 1 + } + } + if (grow >= 1.) { + do j = 1, npts { + do i = n[j]+1, nimages + Memi[id[i]+j-1] = 0 + } + } + } else { + do i = 1, nused { + dp = d[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) + Memi[d[k]+j-1] = Memi[dp] + } + dp = dp + 1 + mp = mp + 1 + } + } + } + } + + # Sort the pixels and IDs if needed + if (mclip) { + call malloc (dp, nimages, TY_INT) + if (keepids) { + call malloc (ip, nimages, TY_INT) + call ic_2sorti (d, Memi[dp], id, Memi[ip], n, npts) + call mfree (ip, TY_INT) + } else + call ic_sorti (d, Memi[dp], n, npts) + call mfree (dp, TY_INT) + } +end + +# IC_GDATA -- Get line of image and mask data and apply threshold and scaling. +# Entirely empty lines are excluded. The data are compacted within the +# input data buffers. If it is required, the connection to the original +# image index is kept in the returned m data pointers. + +procedure ic_gdatar (in, out, dbuf, d, id, n, m, lflag, offsets, scales, + zeros, nimages, npts, v1, v2) + +pointer in[nimages] # Input images +pointer out[3] # Output images +pointer dbuf[nimages] # Data buffers +pointer d[nimages] # Data pointers +pointer id[nimages] # ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Empty mask flags +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +int nimages # Number of input images +int npts # NUmber of output points per line +long v1[ARB], v2[ARB] # Line vectors + +int i, j, k, l, ndim, nused +real a, b +pointer buf, dp, ip, mp, imgnlr() + +include "../icombine.com" + +begin + # Get masks and return if there is no data + call ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + if (dflag == D_NONE) { + call aclri (n, npts) + return + } + + # Get data and fill data buffers. Correct for offsets if needed. + ndim = IM_NDIM(out[1]) + do i = 1, nimages { + if (lflag[i] == D_NONE) + next + if (dbuf[i] == NULL) { + call amovl (v1, v2, IM_MAXDIM) + if (project) + v2[ndim+1] = i + j = imgnlr (in[i], d[i], v2) + } else { + v2[1] = v1[1] + do j = 2, ndim + v2[j] = v1[j] - offsets[i,j] + if (project) + v2[ndim+1] = i + j = imgnlr (in[i], buf, v2) + call amovr (Memr[buf], Memr[dbuf[i]+offsets[i,1]], + IM_LEN(in[i],1)) + d[i] = dbuf[i] + } + } + + # Apply threshold if needed + if (dothresh) { + do i = 1, nimages { + dp = d[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + a = Memr[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + lflag[i] = D_MIX + dflag = D_MIX + } + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + a = Memr[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + dflag = D_MIX + } + } + dp = dp + 1 + mp = mp + 1 + } + } + + # Check for completely empty lines + if (lflag[i] == D_MIX) { + lflag[i] = D_NONE + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + lflag[i] = D_MIX + break + } + mp = mp + 1 + } + } + } + } + + # Apply scaling (avoiding masked pixels which might overflow?) + if (doscale) { + if (dflag == D_ALL) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + do j = 1, npts { + Memr[dp] = Memr[dp] / a + b + dp = dp + 1 + } + } + } else if (dflag == D_MIX) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + Memr[dp] = Memr[dp] / a + b + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) + Memr[dp] = Memr[dp] / a + b + dp = dp + 1 + mp = mp + 1 + } + } + } + } + } + + # Sort pointers to exclude unused images. + # Use the lflag array to keep track of the image index. + + if (dflag == D_ALL) + nused = nimages + else { + nused = 0 + do i = 1, nimages + if (lflag[i] != D_NONE) { + nused = nused + 1 + d[nused] = d[i] + m[nused] = m[i] + lflag[nused] = i + } + if (nused == 0) + dflag = D_NONE + } + + # Compact data to remove bad pixels + # Keep track of the image indices if needed + # If growing mark the end of the included image indices with zero + + if (dflag == D_ALL) { + call amovki (nused, n, npts) + if (keepids) + do i = 1, nimages + call amovki (i, Memi[id[i]], npts) + } else if (dflag == D_NONE) + call aclri (n, npts) + else { + call aclri (n, npts) + if (keepids) { + do i = 1, nused { + l = lflag[i] + dp = d[i] + ip = id[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) { + Memr[d[k]+j-1] = Memr[dp] + Memi[id[k]+j-1] = l + } else + Memi[ip] = l + } + dp = dp + 1 + ip = ip + 1 + mp = mp + 1 + } + } + if (grow >= 1.) { + do j = 1, npts { + do i = n[j]+1, nimages + Memi[id[i]+j-1] = 0 + } + } + } else { + do i = 1, nused { + dp = d[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) + Memr[d[k]+j-1] = Memr[dp] + } + dp = dp + 1 + mp = mp + 1 + } + } + } + } + + # Sort the pixels and IDs if needed + if (mclip) { + call malloc (dp, nimages, TY_REAL) + if (keepids) { + call malloc (ip, nimages, TY_INT) + call ic_2sortr (d, Memr[dp], id, Memi[ip], n, npts) + call mfree (ip, TY_INT) + } else + call ic_sortr (d, Memr[dp], n, npts) + call mfree (dp, TY_REAL) + } +end + +# IC_GDATA -- Get line of image and mask data and apply threshold and scaling. +# Entirely empty lines are excluded. The data are compacted within the +# input data buffers. If it is required, the connection to the original +# image index is kept in the returned m data pointers. + +procedure ic_gdatad (in, out, dbuf, d, id, n, m, lflag, offsets, scales, + zeros, nimages, npts, v1, v2) + +pointer in[nimages] # Input images +pointer out[3] # Output images +pointer dbuf[nimages] # Data buffers +pointer d[nimages] # Data pointers +pointer id[nimages] # ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Empty mask flags +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +int nimages # Number of input images +int npts # NUmber of output points per line +long v1[ARB], v2[ARB] # Line vectors + +int i, j, k, l, ndim, nused +real a, b +pointer buf, dp, ip, mp, imgnld() + +include "../icombine.com" + +begin + # Get masks and return if there is no data + call ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + if (dflag == D_NONE) { + call aclri (n, npts) + return + } + + # Get data and fill data buffers. Correct for offsets if needed. + ndim = IM_NDIM(out[1]) + do i = 1, nimages { + if (lflag[i] == D_NONE) + next + if (dbuf[i] == NULL) { + call amovl (v1, v2, IM_MAXDIM) + if (project) + v2[ndim+1] = i + j = imgnld (in[i], d[i], v2) + } else { + v2[1] = v1[1] + do j = 2, ndim + v2[j] = v1[j] - offsets[i,j] + if (project) + v2[ndim+1] = i + j = imgnld (in[i], buf, v2) + call amovd (Memd[buf], Memd[dbuf[i]+offsets[i,1]], + IM_LEN(in[i],1)) + d[i] = dbuf[i] + } + } + + # Apply threshold if needed + if (dothresh) { + do i = 1, nimages { + dp = d[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + a = Memd[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + lflag[i] = D_MIX + dflag = D_MIX + } + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + a = Memd[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + dflag = D_MIX + } + } + dp = dp + 1 + mp = mp + 1 + } + } + + # Check for completely empty lines + if (lflag[i] == D_MIX) { + lflag[i] = D_NONE + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + lflag[i] = D_MIX + break + } + mp = mp + 1 + } + } + } + } + + # Apply scaling (avoiding masked pixels which might overflow?) + if (doscale) { + if (dflag == D_ALL) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + do j = 1, npts { + Memd[dp] = Memd[dp] / a + b + dp = dp + 1 + } + } + } else if (dflag == D_MIX) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + Memd[dp] = Memd[dp] / a + b + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) + Memd[dp] = Memd[dp] / a + b + dp = dp + 1 + mp = mp + 1 + } + } + } + } + } + + # Sort pointers to exclude unused images. + # Use the lflag array to keep track of the image index. + + if (dflag == D_ALL) + nused = nimages + else { + nused = 0 + do i = 1, nimages + if (lflag[i] != D_NONE) { + nused = nused + 1 + d[nused] = d[i] + m[nused] = m[i] + lflag[nused] = i + } + if (nused == 0) + dflag = D_NONE + } + + # Compact data to remove bad pixels + # Keep track of the image indices if needed + # If growing mark the end of the included image indices with zero + + if (dflag == D_ALL) { + call amovki (nused, n, npts) + if (keepids) + do i = 1, nimages + call amovki (i, Memi[id[i]], npts) + } else if (dflag == D_NONE) + call aclri (n, npts) + else { + call aclri (n, npts) + if (keepids) { + do i = 1, nused { + l = lflag[i] + dp = d[i] + ip = id[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) { + Memd[d[k]+j-1] = Memd[dp] + Memi[id[k]+j-1] = l + } else + Memi[ip] = l + } + dp = dp + 1 + ip = ip + 1 + mp = mp + 1 + } + } + if (grow >= 1.) { + do j = 1, npts { + do i = n[j]+1, nimages + Memi[id[i]+j-1] = 0 + } + } + } else { + do i = 1, nused { + dp = d[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) + Memd[d[k]+j-1] = Memd[dp] + } + dp = dp + 1 + mp = mp + 1 + } + } + } + } + + # Sort the pixels and IDs if needed + if (mclip) { + call malloc (dp, nimages, TY_DOUBLE) + if (keepids) { + call malloc (ip, nimages, TY_INT) + call ic_2sortd (d, Memd[dp], id, Memi[ip], n, npts) + call mfree (ip, TY_INT) + } else + call ic_sortd (d, Memd[dp], n, npts) + call mfree (dp, TY_DOUBLE) + } +end diff --git a/pkg/obsolete/imcombine/generic/icgrow.x b/pkg/obsolete/imcombine/generic/icgrow.x new file mode 100644 index 00000000..d47af927 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icgrow.x @@ -0,0 +1,251 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <pmset.h> +include "../icombine.h" + +# IC_GROW -- Mark neigbors of rejected pixels. +# The rejected pixels (original plus grown) are saved in pixel masks. + +procedure ic_grow (out, v, m, n, buf, nimages, npts, pms) + +pointer out # Output image pointer +long v[ARB] # Output vector +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[npts,nimages] # Working buffer +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k, l, line, nl, rop, igrow, nset, or() +real grow2, i2 +pointer mp, pm, pm_newmask() +errchk pm_newmask() + +include "../icombine.com" + +begin + if (dflag == D_NONE || grow == 0.) + return + + line = v[2] + nl = IM_LEN(out,2) + rop = or (PIX_SRC, PIX_DST) + + igrow = grow + grow2 = grow**2 + do l = 0, igrow { + i2 = grow2 - l * l + call aclri (buf, npts*nimages) + nset = 0 + do j = 1, npts { + do k = n[j]+1, nimages { + mp = Memi[m[k]+j-1] + if (mp == 0) + next + do i = 0, igrow { + if (i**2 > i2) + next + if (j > i) + buf[j-i,mp] = 1 + if (j+i <= npts) + buf[j+i,mp] = 1 + nset = nset + 1 + } + } + } + if (nset == 0) + return + + if (pms == NULL) { + call malloc (pms, nimages, TY_POINTER) + do i = 1, nimages + Memi[pms+i-1] = pm_newmask (out, 1) + } + do i = 1, nimages { + pm = Memi[pms+i-1] + v[2] = line - l + if (v[2] > 0) + call pmplpi (pm, v, buf[1,i], 1, npts, rop) + v[2] = line + l + if (v[2] <= nl) + call pmplpi (pm, v, buf[1,i], 1, npts, rop) + } + } + v[2] = line +end + + + +# IC_GROW$T -- Reject pixels. + +procedure ic_grows (v, d, m, n, buf, nimages, npts, pms) + +long v[ARB] # Output vector +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[ARB] # Buffer of npts +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k +pointer pm +bool pl_linenotempty() + +include "../icombine.com" + +begin + do k = 1, nimages { + pm = Memi[pms+k-1] + if (!pl_linenotempty (pm, v)) + next + call pmglpi (pm, v, buf, 1, npts, PIX_SRC) + do i = 1, npts { + if (buf[i] == 0) + next + for (j = 1; j <= n[i]; j = j + 1) { + if (Memi[m[j]+i-1] == k) { + if (j < n[i]) { + Mems[d[j]+i-1] = Mems[d[n[i]]+i-1] + Memi[m[j]+i-1] = Memi[m[n[i]]+i-1] + } + n[i] = n[i] - 1 + dflag = D_MIX + break + } + } + } + } +end + +# IC_GROW$T -- Reject pixels. + +procedure ic_growi (v, d, m, n, buf, nimages, npts, pms) + +long v[ARB] # Output vector +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[ARB] # Buffer of npts +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k +pointer pm +bool pl_linenotempty() + +include "../icombine.com" + +begin + do k = 1, nimages { + pm = Memi[pms+k-1] + if (!pl_linenotempty (pm, v)) + next + call pmglpi (pm, v, buf, 1, npts, PIX_SRC) + do i = 1, npts { + if (buf[i] == 0) + next + for (j = 1; j <= n[i]; j = j + 1) { + if (Memi[m[j]+i-1] == k) { + if (j < n[i]) { + Memi[d[j]+i-1] = Memi[d[n[i]]+i-1] + Memi[m[j]+i-1] = Memi[m[n[i]]+i-1] + } + n[i] = n[i] - 1 + dflag = D_MIX + break + } + } + } + } +end + +# IC_GROW$T -- Reject pixels. + +procedure ic_growr (v, d, m, n, buf, nimages, npts, pms) + +long v[ARB] # Output vector +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[ARB] # Buffer of npts +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k +pointer pm +bool pl_linenotempty() + +include "../icombine.com" + +begin + do k = 1, nimages { + pm = Memi[pms+k-1] + if (!pl_linenotempty (pm, v)) + next + call pmglpi (pm, v, buf, 1, npts, PIX_SRC) + do i = 1, npts { + if (buf[i] == 0) + next + for (j = 1; j <= n[i]; j = j + 1) { + if (Memi[m[j]+i-1] == k) { + if (j < n[i]) { + Memr[d[j]+i-1] = Memr[d[n[i]]+i-1] + Memi[m[j]+i-1] = Memi[m[n[i]]+i-1] + } + n[i] = n[i] - 1 + dflag = D_MIX + break + } + } + } + } +end + +# IC_GROW$T -- Reject pixels. + +procedure ic_growd (v, d, m, n, buf, nimages, npts, pms) + +long v[ARB] # Output vector +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[ARB] # Buffer of npts +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k +pointer pm +bool pl_linenotempty() + +include "../icombine.com" + +begin + do k = 1, nimages { + pm = Memi[pms+k-1] + if (!pl_linenotempty (pm, v)) + next + call pmglpi (pm, v, buf, 1, npts, PIX_SRC) + do i = 1, npts { + if (buf[i] == 0) + next + for (j = 1; j <= n[i]; j = j + 1) { + if (Memi[m[j]+i-1] == k) { + if (j < n[i]) { + Memd[d[j]+i-1] = Memd[d[n[i]]+i-1] + Memi[m[j]+i-1] = Memi[m[n[i]]+i-1] + } + n[i] = n[i] - 1 + dflag = D_MIX + break + } + } + } + } +end diff --git a/pkg/obsolete/imcombine/generic/icmedian.x b/pkg/obsolete/imcombine/generic/icmedian.x new file mode 100644 index 00000000..80f36443 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icmedian.x @@ -0,0 +1,556 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + + +# IC_MEDIAN -- Median of lines + +procedure ic_medians (d, n, npts, doblank, median) + +pointer d[ARB] # Input data line pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line +int doblank # Set blank values? +real median[npts] # Median + +int i, j1, j2, j3, k, n1 +bool even +real val1, val2, val3 + +include "../icombine.com" + +begin + if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + median[i]= blank + } + return + } + + # Check for previous sorting + if (mclip) { + if (dflag == D_ALL) { + n1 = n[1] + even = (mod (n1, 2) == 0) + j1 = n1 / 2 + 1 + j2 = n1 / 2 + do i = 1, npts { + k = i - 1 + if (even) { + val1 = Mems[d[j1]+k] + val2 = Mems[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Mems[d[j1]+k] + } + } else { + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 > 0) { + j1 = n1 / 2 + 1 + if (mod (n1, 2) == 0) { + j2 = n1 / 2 + val1 = Mems[d[j1]+k] + val2 = Mems[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Mems[d[j1]+k] + } else if (doblank == YES) + median[i] = blank + } + } + return + } + + # Repeatedly exchange the extreme values until there are three + # or fewer pixels. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + while (n1 > 3) { + j1 = 1 + j2 = 1 + val1 = Mems[d[j1]+k] + val2 = val1 + do j3 = 2, n1 { + val3 = Mems[d[j3]+k] + if (val3 > val1) { + j1 = j3 + val1 = val3 + } else if (val3 < val2) { + j2 = j3 + val2 = val3 + } + } + j3 = n1 - 1 + if (j1 < j3 && j2 < j3) { + Mems[d[j1]+k] = val3 + Mems[d[j2]+k] = Mems[d[j3]+k] + Mems[d[j3]+k] = val1 + Mems[d[n1]+k] = val2 + } else if (j1 < j3) { + if (j2 == j3) { + Mems[d[j1]+k] = val3 + Mems[d[n1]+k] = val1 + } else { + Mems[d[j1]+k] = Mems[d[j3]+k] + Mems[d[j3]+k] = val1 + } + } else if (j2 < j3) { + if (j1 == j3) { + Mems[d[j2]+k] = val3 + Mems[d[n1]+k] = val2 + } else { + Mems[d[j2]+k] = Mems[d[j3]+k] + Mems[d[j3]+k] = val2 + } + } + n1 = n1 - 2 + } + + if (n1 == 3) { + val1 = Mems[d[1]+k] + val2 = Mems[d[2]+k] + val3 = Mems[d[3]+k] + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = val2 + else if (val1 < val3) # acb + median[i] = val3 + else # cab + median[i] = val1 + } else { + if (val2 > val3) # cba + median[i] = val2 + else if (val1 > val3) # bca + median[i] = val3 + else # bac + median[i] = val1 + } + } else if (n1 == 2) { + val1 = Mems[d[1]+k] + val2 = Mems[d[2]+k] + median[i] = (val1 + val2) / 2 + } else if (n1 == 1) + median[i] = Mems[d[1]+k] + else if (doblank == YES) + median[i] = blank + } +end + +# IC_MEDIAN -- Median of lines + +procedure ic_mediani (d, n, npts, doblank, median) + +pointer d[ARB] # Input data line pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line +int doblank # Set blank values? +real median[npts] # Median + +int i, j1, j2, j3, k, n1 +bool even +real val1, val2, val3 + +include "../icombine.com" + +begin + if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + median[i]= blank + } + return + } + + # Check for previous sorting + if (mclip) { + if (dflag == D_ALL) { + n1 = n[1] + even = (mod (n1, 2) == 0) + j1 = n1 / 2 + 1 + j2 = n1 / 2 + do i = 1, npts { + k = i - 1 + if (even) { + val1 = Memi[d[j1]+k] + val2 = Memi[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memi[d[j1]+k] + } + } else { + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 > 0) { + j1 = n1 / 2 + 1 + if (mod (n1, 2) == 0) { + j2 = n1 / 2 + val1 = Memi[d[j1]+k] + val2 = Memi[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memi[d[j1]+k] + } else if (doblank == YES) + median[i] = blank + } + } + return + } + + # Repeatedly exchange the extreme values until there are three + # or fewer pixels. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + while (n1 > 3) { + j1 = 1 + j2 = 1 + val1 = Memi[d[j1]+k] + val2 = val1 + do j3 = 2, n1 { + val3 = Memi[d[j3]+k] + if (val3 > val1) { + j1 = j3 + val1 = val3 + } else if (val3 < val2) { + j2 = j3 + val2 = val3 + } + } + j3 = n1 - 1 + if (j1 < j3 && j2 < j3) { + Memi[d[j1]+k] = val3 + Memi[d[j2]+k] = Memi[d[j3]+k] + Memi[d[j3]+k] = val1 + Memi[d[n1]+k] = val2 + } else if (j1 < j3) { + if (j2 == j3) { + Memi[d[j1]+k] = val3 + Memi[d[n1]+k] = val1 + } else { + Memi[d[j1]+k] = Memi[d[j3]+k] + Memi[d[j3]+k] = val1 + } + } else if (j2 < j3) { + if (j1 == j3) { + Memi[d[j2]+k] = val3 + Memi[d[n1]+k] = val2 + } else { + Memi[d[j2]+k] = Memi[d[j3]+k] + Memi[d[j3]+k] = val2 + } + } + n1 = n1 - 2 + } + + if (n1 == 3) { + val1 = Memi[d[1]+k] + val2 = Memi[d[2]+k] + val3 = Memi[d[3]+k] + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = val2 + else if (val1 < val3) # acb + median[i] = val3 + else # cab + median[i] = val1 + } else { + if (val2 > val3) # cba + median[i] = val2 + else if (val1 > val3) # bca + median[i] = val3 + else # bac + median[i] = val1 + } + } else if (n1 == 2) { + val1 = Memi[d[1]+k] + val2 = Memi[d[2]+k] + median[i] = (val1 + val2) / 2 + } else if (n1 == 1) + median[i] = Memi[d[1]+k] + else if (doblank == YES) + median[i] = blank + } +end + +# IC_MEDIAN -- Median of lines + +procedure ic_medianr (d, n, npts, doblank, median) + +pointer d[ARB] # Input data line pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line +int doblank # Set blank values? +real median[npts] # Median + +int i, j1, j2, j3, k, n1 +bool even +real val1, val2, val3 + +include "../icombine.com" + +begin + if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + median[i]= blank + } + return + } + + # Check for previous sorting + if (mclip) { + if (dflag == D_ALL) { + n1 = n[1] + even = (mod (n1, 2) == 0) + j1 = n1 / 2 + 1 + j2 = n1 / 2 + do i = 1, npts { + k = i - 1 + if (even) { + val1 = Memr[d[j1]+k] + val2 = Memr[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memr[d[j1]+k] + } + } else { + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 > 0) { + j1 = n1 / 2 + 1 + if (mod (n1, 2) == 0) { + j2 = n1 / 2 + val1 = Memr[d[j1]+k] + val2 = Memr[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memr[d[j1]+k] + } else if (doblank == YES) + median[i] = blank + } + } + return + } + + # Repeatedly exchange the extreme values until there are three + # or fewer pixels. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + while (n1 > 3) { + j1 = 1 + j2 = 1 + val1 = Memr[d[j1]+k] + val2 = val1 + do j3 = 2, n1 { + val3 = Memr[d[j3]+k] + if (val3 > val1) { + j1 = j3 + val1 = val3 + } else if (val3 < val2) { + j2 = j3 + val2 = val3 + } + } + j3 = n1 - 1 + if (j1 < j3 && j2 < j3) { + Memr[d[j1]+k] = val3 + Memr[d[j2]+k] = Memr[d[j3]+k] + Memr[d[j3]+k] = val1 + Memr[d[n1]+k] = val2 + } else if (j1 < j3) { + if (j2 == j3) { + Memr[d[j1]+k] = val3 + Memr[d[n1]+k] = val1 + } else { + Memr[d[j1]+k] = Memr[d[j3]+k] + Memr[d[j3]+k] = val1 + } + } else if (j2 < j3) { + if (j1 == j3) { + Memr[d[j2]+k] = val3 + Memr[d[n1]+k] = val2 + } else { + Memr[d[j2]+k] = Memr[d[j3]+k] + Memr[d[j3]+k] = val2 + } + } + n1 = n1 - 2 + } + + if (n1 == 3) { + val1 = Memr[d[1]+k] + val2 = Memr[d[2]+k] + val3 = Memr[d[3]+k] + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = val2 + else if (val1 < val3) # acb + median[i] = val3 + else # cab + median[i] = val1 + } else { + if (val2 > val3) # cba + median[i] = val2 + else if (val1 > val3) # bca + median[i] = val3 + else # bac + median[i] = val1 + } + } else if (n1 == 2) { + val1 = Memr[d[1]+k] + val2 = Memr[d[2]+k] + median[i] = (val1 + val2) / 2 + } else if (n1 == 1) + median[i] = Memr[d[1]+k] + else if (doblank == YES) + median[i] = blank + } +end + +# IC_MEDIAN -- Median of lines + +procedure ic_mediand (d, n, npts, doblank, median) + +pointer d[ARB] # Input data line pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line +int doblank # Set blank values? +double median[npts] # Median + +int i, j1, j2, j3, k, n1 +bool even +double val1, val2, val3 + +include "../icombine.com" + +begin + if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + median[i]= blank + } + return + } + + # Check for previous sorting + if (mclip) { + if (dflag == D_ALL) { + n1 = n[1] + even = (mod (n1, 2) == 0) + j1 = n1 / 2 + 1 + j2 = n1 / 2 + do i = 1, npts { + k = i - 1 + if (even) { + val1 = Memd[d[j1]+k] + val2 = Memd[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memd[d[j1]+k] + } + } else { + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 > 0) { + j1 = n1 / 2 + 1 + if (mod (n1, 2) == 0) { + j2 = n1 / 2 + val1 = Memd[d[j1]+k] + val2 = Memd[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Memd[d[j1]+k] + } else if (doblank == YES) + median[i] = blank + } + } + return + } + + # Repeatedly exchange the extreme values until there are three + # or fewer pixels. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + while (n1 > 3) { + j1 = 1 + j2 = 1 + val1 = Memd[d[j1]+k] + val2 = val1 + do j3 = 2, n1 { + val3 = Memd[d[j3]+k] + if (val3 > val1) { + j1 = j3 + val1 = val3 + } else if (val3 < val2) { + j2 = j3 + val2 = val3 + } + } + j3 = n1 - 1 + if (j1 < j3 && j2 < j3) { + Memd[d[j1]+k] = val3 + Memd[d[j2]+k] = Memd[d[j3]+k] + Memd[d[j3]+k] = val1 + Memd[d[n1]+k] = val2 + } else if (j1 < j3) { + if (j2 == j3) { + Memd[d[j1]+k] = val3 + Memd[d[n1]+k] = val1 + } else { + Memd[d[j1]+k] = Memd[d[j3]+k] + Memd[d[j3]+k] = val1 + } + } else if (j2 < j3) { + if (j1 == j3) { + Memd[d[j2]+k] = val3 + Memd[d[n1]+k] = val2 + } else { + Memd[d[j2]+k] = Memd[d[j3]+k] + Memd[d[j3]+k] = val2 + } + } + n1 = n1 - 2 + } + + if (n1 == 3) { + val1 = Memd[d[1]+k] + val2 = Memd[d[2]+k] + val3 = Memd[d[3]+k] + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = val2 + else if (val1 < val3) # acb + median[i] = val3 + else # cab + median[i] = val1 + } else { + if (val2 > val3) # cba + median[i] = val2 + else if (val1 > val3) # bca + median[i] = val3 + else # bac + median[i] = val1 + } + } else if (n1 == 2) { + val1 = Memd[d[1]+k] + val2 = Memd[d[2]+k] + median[i] = (val1 + val2) / 2 + } else if (n1 == 1) + median[i] = Memd[d[1]+k] + else if (doblank == YES) + median[i] = blank + } +end diff --git a/pkg/obsolete/imcombine/generic/icmm.x b/pkg/obsolete/imcombine/generic/icmm.x new file mode 100644 index 00000000..fc1a9239 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icmm.x @@ -0,0 +1,612 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + + +# IC_MM -- Reject a specified number of high and low pixels + +procedure ic_mms (d, m, n, npts) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line + +int n1, ncombine, npairs, nlow, nhigh, np +int i, i1, j, jmax, jmin +pointer k, kmax, kmin +short d1, d2, dmin, dmax + +include "../icombine.com" + +begin + if (dflag == D_NONE) + return + + if (dflag == D_ALL) { + n1 = n[1] + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = n1 - nlow - nhigh + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + do i = 1, npts { + i1 = i - 1 + n1 = n[i] + if (dflag == D_MIX) { + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = max (ncombine, n1 - nlow - nhigh) + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + # Reject the npairs low and high points. + do np = 1, npairs { + k = d[1] + i1 + d1 = Mems[k] + dmax = d1; dmin = d1; jmax = 1; jmin = 1; kmax = k; kmin = k + do j = 2, n1 { + d2 = d1 + k = d[j] + i1 + d1 = Mems[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } else if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + j = n1 - 1 + if (keepids) { + if (jmax < j) { + if (jmin != j) { + Mems[kmax] = d2 + Memi[m[jmax]+i1] = Memi[m[j]+i1] + } else { + Mems[kmax] = d1 + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + } + } + if (jmin < j) { + if (jmax != n1) { + Mems[kmin] = d1 + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + } else { + Mems[kmin] = d2 + Memi[m[jmin]+i1] = Memi[m[j]+i1] + } + } + } else { + if (jmax < j) { + if (jmin != j) + Mems[kmax] = d2 + else + Mems[kmax] = d1 + } + if (jmin < j) { + if (jmax != n1) + Mems[kmin] = d1 + else + Mems[kmin] = d2 + } + } + n1 = n1 - 2 + } + + # Reject the excess low points. + do np = 1, nlow { + k = d[1] + i1 + d1 = Mems[k] + dmin = d1; jmin = 1; kmin = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Mems[k] + if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + if (keepids) { + if (jmin < n1) { + Mems[kmin] = d1 + k = Memi[m[jmin]+i1] + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmin < n1) + Mems[kmin] = d1 + } + n1 = n1 - 1 + } + + # Reject the excess high points. + do np = 1, nhigh { + k = d[1] + i1 + d1 = Mems[k] + dmax = d1; jmax = 1; kmax = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Mems[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } + } + if (keepids) { + if (jmax < n1) { + Mems[kmax] = d1 + k = Memi[m[jmax]+i1] + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmax < n1) + Mems[kmax] = d1 + } + n1 = n1 - 1 + } + n[i] = n1 + } + + if (dflag == D_ALL && npairs + nlow + nhigh > 0) + dflag = D_MIX +end + +# IC_MM -- Reject a specified number of high and low pixels + +procedure ic_mmi (d, m, n, npts) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line + +int n1, ncombine, npairs, nlow, nhigh, np +int i, i1, j, jmax, jmin +pointer k, kmax, kmin +int d1, d2, dmin, dmax + +include "../icombine.com" + +begin + if (dflag == D_NONE) + return + + if (dflag == D_ALL) { + n1 = n[1] + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = n1 - nlow - nhigh + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + do i = 1, npts { + i1 = i - 1 + n1 = n[i] + if (dflag == D_MIX) { + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = max (ncombine, n1 - nlow - nhigh) + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + # Reject the npairs low and high points. + do np = 1, npairs { + k = d[1] + i1 + d1 = Memi[k] + dmax = d1; dmin = d1; jmax = 1; jmin = 1; kmax = k; kmin = k + do j = 2, n1 { + d2 = d1 + k = d[j] + i1 + d1 = Memi[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } else if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + j = n1 - 1 + if (keepids) { + if (jmax < j) { + if (jmin != j) { + Memi[kmax] = d2 + Memi[m[jmax]+i1] = Memi[m[j]+i1] + } else { + Memi[kmax] = d1 + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + } + } + if (jmin < j) { + if (jmax != n1) { + Memi[kmin] = d1 + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + } else { + Memi[kmin] = d2 + Memi[m[jmin]+i1] = Memi[m[j]+i1] + } + } + } else { + if (jmax < j) { + if (jmin != j) + Memi[kmax] = d2 + else + Memi[kmax] = d1 + } + if (jmin < j) { + if (jmax != n1) + Memi[kmin] = d1 + else + Memi[kmin] = d2 + } + } + n1 = n1 - 2 + } + + # Reject the excess low points. + do np = 1, nlow { + k = d[1] + i1 + d1 = Memi[k] + dmin = d1; jmin = 1; kmin = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memi[k] + if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + if (keepids) { + if (jmin < n1) { + Memi[kmin] = d1 + k = Memi[m[jmin]+i1] + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmin < n1) + Memi[kmin] = d1 + } + n1 = n1 - 1 + } + + # Reject the excess high points. + do np = 1, nhigh { + k = d[1] + i1 + d1 = Memi[k] + dmax = d1; jmax = 1; kmax = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memi[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } + } + if (keepids) { + if (jmax < n1) { + Memi[kmax] = d1 + k = Memi[m[jmax]+i1] + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmax < n1) + Memi[kmax] = d1 + } + n1 = n1 - 1 + } + n[i] = n1 + } + + if (dflag == D_ALL && npairs + nlow + nhigh > 0) + dflag = D_MIX +end + +# IC_MM -- Reject a specified number of high and low pixels + +procedure ic_mmr (d, m, n, npts) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line + +int n1, ncombine, npairs, nlow, nhigh, np +int i, i1, j, jmax, jmin +pointer k, kmax, kmin +real d1, d2, dmin, dmax + +include "../icombine.com" + +begin + if (dflag == D_NONE) + return + + if (dflag == D_ALL) { + n1 = n[1] + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = n1 - nlow - nhigh + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + do i = 1, npts { + i1 = i - 1 + n1 = n[i] + if (dflag == D_MIX) { + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = max (ncombine, n1 - nlow - nhigh) + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + # Reject the npairs low and high points. + do np = 1, npairs { + k = d[1] + i1 + d1 = Memr[k] + dmax = d1; dmin = d1; jmax = 1; jmin = 1; kmax = k; kmin = k + do j = 2, n1 { + d2 = d1 + k = d[j] + i1 + d1 = Memr[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } else if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + j = n1 - 1 + if (keepids) { + if (jmax < j) { + if (jmin != j) { + Memr[kmax] = d2 + Memi[m[jmax]+i1] = Memi[m[j]+i1] + } else { + Memr[kmax] = d1 + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + } + } + if (jmin < j) { + if (jmax != n1) { + Memr[kmin] = d1 + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + } else { + Memr[kmin] = d2 + Memi[m[jmin]+i1] = Memi[m[j]+i1] + } + } + } else { + if (jmax < j) { + if (jmin != j) + Memr[kmax] = d2 + else + Memr[kmax] = d1 + } + if (jmin < j) { + if (jmax != n1) + Memr[kmin] = d1 + else + Memr[kmin] = d2 + } + } + n1 = n1 - 2 + } + + # Reject the excess low points. + do np = 1, nlow { + k = d[1] + i1 + d1 = Memr[k] + dmin = d1; jmin = 1; kmin = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memr[k] + if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + if (keepids) { + if (jmin < n1) { + Memr[kmin] = d1 + k = Memi[m[jmin]+i1] + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmin < n1) + Memr[kmin] = d1 + } + n1 = n1 - 1 + } + + # Reject the excess high points. + do np = 1, nhigh { + k = d[1] + i1 + d1 = Memr[k] + dmax = d1; jmax = 1; kmax = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memr[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } + } + if (keepids) { + if (jmax < n1) { + Memr[kmax] = d1 + k = Memi[m[jmax]+i1] + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmax < n1) + Memr[kmax] = d1 + } + n1 = n1 - 1 + } + n[i] = n1 + } + + if (dflag == D_ALL && npairs + nlow + nhigh > 0) + dflag = D_MIX +end + +# IC_MM -- Reject a specified number of high and low pixels + +procedure ic_mmd (d, m, n, npts) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line + +int n1, ncombine, npairs, nlow, nhigh, np +int i, i1, j, jmax, jmin +pointer k, kmax, kmin +double d1, d2, dmin, dmax + +include "../icombine.com" + +begin + if (dflag == D_NONE) + return + + if (dflag == D_ALL) { + n1 = n[1] + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = n1 - nlow - nhigh + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + do i = 1, npts { + i1 = i - 1 + n1 = n[i] + if (dflag == D_MIX) { + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = max (ncombine, n1 - nlow - nhigh) + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + # Reject the npairs low and high points. + do np = 1, npairs { + k = d[1] + i1 + d1 = Memd[k] + dmax = d1; dmin = d1; jmax = 1; jmin = 1; kmax = k; kmin = k + do j = 2, n1 { + d2 = d1 + k = d[j] + i1 + d1 = Memd[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } else if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + j = n1 - 1 + if (keepids) { + if (jmax < j) { + if (jmin != j) { + Memd[kmax] = d2 + Memi[m[jmax]+i1] = Memi[m[j]+i1] + } else { + Memd[kmax] = d1 + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + } + } + if (jmin < j) { + if (jmax != n1) { + Memd[kmin] = d1 + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + } else { + Memd[kmin] = d2 + Memi[m[jmin]+i1] = Memi[m[j]+i1] + } + } + } else { + if (jmax < j) { + if (jmin != j) + Memd[kmax] = d2 + else + Memd[kmax] = d1 + } + if (jmin < j) { + if (jmax != n1) + Memd[kmin] = d1 + else + Memd[kmin] = d2 + } + } + n1 = n1 - 2 + } + + # Reject the excess low points. + do np = 1, nlow { + k = d[1] + i1 + d1 = Memd[k] + dmin = d1; jmin = 1; kmin = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memd[k] + if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + if (keepids) { + if (jmin < n1) { + Memd[kmin] = d1 + k = Memi[m[jmin]+i1] + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmin < n1) + Memd[kmin] = d1 + } + n1 = n1 - 1 + } + + # Reject the excess high points. + do np = 1, nhigh { + k = d[1] + i1 + d1 = Memd[k] + dmax = d1; jmax = 1; kmax = k + do j = 2, n1 { + k = d[j] + i1 + d1 = Memd[k] + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } + } + if (keepids) { + if (jmax < n1) { + Memd[kmax] = d1 + k = Memi[m[jmax]+i1] + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmax < n1) + Memd[kmax] = d1 + } + n1 = n1 - 1 + } + n[i] = n1 + } + + if (dflag == D_ALL && npairs + nlow + nhigh > 0) + dflag = D_MIX +end diff --git a/pkg/obsolete/imcombine/generic/icombine.x b/pkg/obsolete/imcombine/generic/icombine.x new file mode 100644 index 00000000..50c76cca --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icombine.x @@ -0,0 +1,1645 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <imset.h> +include <pmset.h> +include <error.h> +include <syserr.h> +include <mach.h> +include "../icombine.h" + + +# ICOMBINE -- Combine images +# +# The memory and open file descriptor limits are checked and an attempt +# to recover is made either by setting the image pixel files to be +# closed after I/O or by notifying the calling program that memory +# ran out and the IMIO buffer size should be reduced. After the checks +# a procedure for the selected combine option is called. +# Because there may be several failure modes when reaching the file +# limits we first assume an error is due to the file limit, except for +# out of memory, and close some pixel files. If the error then repeats +# on accessing the pixels the error is passed back. + + +procedure icombines (in, out, offsets, nimages, bufsize) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int offsets[nimages,ARB] # Input image offsets +int nimages # Number of input images +int bufsize # IMIO buffer size + +char str[1] +int i, j, npts, fd, stropen(), errcode(), imstati() +pointer sp, d, id, n, m, lflag, scales, zeros, wts, dbuf +pointer buf, imgl1s(), impl1i() +errchk stropen, imgl1s, impl1i +pointer impl1r() +errchk impl1r + +include "../icombine.com" + +begin + npts = IM_LEN(out[1],1) + + # Allocate memory. + call smark (sp) + call salloc (dbuf, nimages, TY_POINTER) + call salloc (d, nimages, TY_POINTER) + call salloc (id, nimages, TY_POINTER) + call salloc (n, npts, TY_INT) + call salloc (m, nimages, TY_POINTER) + call salloc (lflag, nimages, TY_INT) + call salloc (scales, nimages, TY_REAL) + call salloc (zeros, nimages, TY_REAL) + call salloc (wts, nimages, TY_REAL) + call amovki (D_ALL, Memi[lflag], nimages) + + # If not aligned or growing create data buffers of output length + # otherwise use the IMIO buffers. + + if (!aligned || grow >= 1.) { + do i = 1, nimages + call salloc (Memi[dbuf+i-1], npts, TY_SHORT) + } else + call amovki (NULL, Memi[dbuf], nimages) + + if (project) { + call imseti (in[1], IM_NBUFS, nimages) + call imseti (in[1], IM_BUFSIZE, bufsize) + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + } else { + # Reserve FD for string operations. + fd = stropen (str, 1, NEW_FILE) + + # Do I/O to the images. + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + buf = impl1r (out[1]) + call aclrr (Memr[buf], npts) + if (out[3] != NULL) { + buf = impl1r (out[3]) + call aclrr (Memr[buf], npts) + } + if (out[2] != NULL) { + buf = impl1i (out[2]) + call aclri (Memi[buf], npts) + } + + do i = 1, nimages { + call imseti (in[i], IM_BUFSIZE, bufsize) + iferr (buf = imgl1s (in[i])) { + switch (errcode()) { + case SYS_MFULL: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + case SYS_FTOOMANYFILES, SYS_IKIOPIX: + if (imstati (in[i], IM_CLOSEFD) == YES) { + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + do j = i-2, nimages + call imseti (in[j], IM_CLOSEFD, YES) + buf = imgl1s (in[i]) + default: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + } + } + + call strclose (fd) + } + + call ic_combines (in, out, Memi[dbuf], Memi[d], Memi[id], Memi[n], + Memi[m], Memi[lflag], offsets, Memr[scales], Memr[zeros], + Memr[wts], nimages, npts) +end + + +# IC_COMBINE -- Combine images. + +procedure ic_combines (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, wts, nimages, npts) + +pointer in[nimages] # Input images +pointer out[4] # Output image +pointer dbuf[nimages] # Data buffers for nonaligned images +pointer d[nimages] # Data pointers +pointer id[nimages] # Image index ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Line flags +int offsets[nimages,ARB] # Input image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +real wts[nimages] # Combining weights +int nimages # Number of input images +int npts # Number of points per output line + +int i, ext, ctor(), ic_qsort(), errcode() +real r, imgetr() +pointer sp, fname, imname, v1, v2, v3, work +pointer outdata, buf, nm, pms +pointer immap(), impnli() +pointer impnlr(), imgnlr() +errchk immap, ic_scale, imgetr, ic_grow, ic_grows, ic_rmasks +extern ic_qsort + +include "../icombine.com" +data ext/0/ + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (imname, SZ_FNAME, TY_CHAR) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (v3, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + + call ic_scale (in, out, offsets, scales, zeros, wts, nimages) + + # Set combine parameters + switch (combine) { + case AVERAGE: + if (dowts) + keepids = true + else + keepids = false + case MEDIAN: + dowts = false + keepids = false + } + docombine = true + + # Set rejection algorithm specific parameters + switch (reject) { + case CCDCLIP, CRREJECT: + call salloc (nm, 3*nimages, TY_REAL) + i = 1 + if (ctor (Memc[rdnoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)] = r + } else { + do i = 1, nimages + Memr[nm+3*(i-1)] = imgetr (in[i], Memc[rdnoise]) + } + i = 1 + if (ctor (Memc[gain], i, r) > 0) { + do i = 1, nimages { + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[gain]) + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } + i = 1 + if (ctor (Memc[snoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)+2] = r + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[snoise]) + Memr[nm+3*(i-1)+2] = r + } + } + if (!keepids) { + if (doscale1) + keepids = true + else { + do i = 2, nimages { + if (Memr[nm+3*(i-1)] != Memr[nm] || + Memr[nm+3*(i-1)+1] != Memr[nm+1] || + Memr[nm+3*(i-1)+2] != Memr[nm+2]) { + keepids = true + break + } + } + } + } + if (reject == CRREJECT) + lsigma = MAX_REAL + case MINMAX: + mclip = false + case PCLIP: + mclip = true + case AVSIGCLIP, SIGCLIP: + if (doscale1) + keepids = true + case NONE: + mclip = false + } + + if (out[4] != NULL) + keepids = true + + if (grow >= 1.) { + keepids = true + call salloc (work, npts * nimages, TY_INT) + } + pms = NULL + + if (keepids) { + do i = 1, nimages + call salloc (id[i], npts, TY_INT) + } + + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatas (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclips (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + else + call ic_accdclips (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + case MINMAX: + call ic_mms (d, id, n, npts) + case PCLIP: + call ic_pclips (d, id, n, nimages, npts, Memr[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclips (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + else + call ic_asigclips (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclips (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + else + call ic_aavsigclips (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_averages (d, id, n, wts, npts, YES, + Memr[outdata]) + case MEDIAN: + call ic_medians (d, n, npts, YES, Memr[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmas (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + if (pms != NULL) { + if (nkeep > 0) { + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call imunmap (out[1]) + iferr (buf = immap (Memc[fname], READ_WRITE, 0)) { + switch (errcode()) { + case SYS_FXFOPNOEXTNV: + call imgcluster (Memc[fname], Memc[fname], SZ_FNAME) + ext = ext + 1 + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext) + iferr (buf = immap (Memc[imname], READ_WRITE, 0)) { + buf = NULL + ext = 0 + } + repeat { + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext+1) + iferr (outdata = immap (Memc[imname],READ_WRITE,0)) + break + if (buf != NULL) + call imunmap (buf) + buf = outdata + ext = ext + 1 + } + default: + call erract (EA_ERROR) + } + } + out[1] = buf + } + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatas (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_grows (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnlr (out[1], buf, Meml[v1]) == EOF) + ; + call amovr (Memr[buf], Memr[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_averages (d, id, n, wts, npts, NO, Memr[outdata]) + case MEDIAN: + call ic_medians (d, n, npts, NO, Memr[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmas (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + do i = 1, nimages + call pm_close (Memi[pms+i-1]) + call mfree (pms, TY_POINTER) + } + + call sfree (sp) +end + +procedure icombinei (in, out, offsets, nimages, bufsize) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int offsets[nimages,ARB] # Input image offsets +int nimages # Number of input images +int bufsize # IMIO buffer size + +char str[1] +int i, j, npts, fd, stropen(), errcode(), imstati() +pointer sp, d, id, n, m, lflag, scales, zeros, wts, dbuf +pointer buf, imgl1i(), impl1i() +errchk stropen, imgl1i, impl1i +pointer impl1r() +errchk impl1r + +include "../icombine.com" + +begin + npts = IM_LEN(out[1],1) + + # Allocate memory. + call smark (sp) + call salloc (dbuf, nimages, TY_POINTER) + call salloc (d, nimages, TY_POINTER) + call salloc (id, nimages, TY_POINTER) + call salloc (n, npts, TY_INT) + call salloc (m, nimages, TY_POINTER) + call salloc (lflag, nimages, TY_INT) + call salloc (scales, nimages, TY_REAL) + call salloc (zeros, nimages, TY_REAL) + call salloc (wts, nimages, TY_REAL) + call amovki (D_ALL, Memi[lflag], nimages) + + # If not aligned or growing create data buffers of output length + # otherwise use the IMIO buffers. + + if (!aligned || grow >= 1.) { + do i = 1, nimages + call salloc (Memi[dbuf+i-1], npts, TY_INT) + } else + call amovki (NULL, Memi[dbuf], nimages) + + if (project) { + call imseti (in[1], IM_NBUFS, nimages) + call imseti (in[1], IM_BUFSIZE, bufsize) + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + } else { + # Reserve FD for string operations. + fd = stropen (str, 1, NEW_FILE) + + # Do I/O to the images. + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + buf = impl1r (out[1]) + call aclrr (Memr[buf], npts) + if (out[3] != NULL) { + buf = impl1r (out[3]) + call aclrr (Memr[buf], npts) + } + if (out[2] != NULL) { + buf = impl1i (out[2]) + call aclri (Memi[buf], npts) + } + + do i = 1, nimages { + call imseti (in[i], IM_BUFSIZE, bufsize) + iferr (buf = imgl1i (in[i])) { + switch (errcode()) { + case SYS_MFULL: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + case SYS_FTOOMANYFILES, SYS_IKIOPIX: + if (imstati (in[i], IM_CLOSEFD) == YES) { + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + do j = i-2, nimages + call imseti (in[j], IM_CLOSEFD, YES) + buf = imgl1i (in[i]) + default: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + } + } + + call strclose (fd) + } + + call ic_combinei (in, out, Memi[dbuf], Memi[d], Memi[id], Memi[n], + Memi[m], Memi[lflag], offsets, Memr[scales], Memr[zeros], + Memr[wts], nimages, npts) +end + + +# IC_COMBINE -- Combine images. + +procedure ic_combinei (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, wts, nimages, npts) + +pointer in[nimages] # Input images +pointer out[4] # Output image +pointer dbuf[nimages] # Data buffers for nonaligned images +pointer d[nimages] # Data pointers +pointer id[nimages] # Image index ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Line flags +int offsets[nimages,ARB] # Input image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +real wts[nimages] # Combining weights +int nimages # Number of input images +int npts # Number of points per output line + +int i, ext, ctor(), ic_qsort(), errcode() +real r, imgetr() +pointer sp, fname, imname, v1, v2, v3, work +pointer outdata, buf, nm, pms +pointer immap(), impnli() +pointer impnlr(), imgnlr() +errchk immap, ic_scale, imgetr, ic_grow, ic_growi, ic_rmasks +extern ic_qsort + +include "../icombine.com" +data ext/0/ + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (imname, SZ_FNAME, TY_CHAR) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (v3, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + + call ic_scale (in, out, offsets, scales, zeros, wts, nimages) + + # Set combine parameters + switch (combine) { + case AVERAGE: + if (dowts) + keepids = true + else + keepids = false + case MEDIAN: + dowts = false + keepids = false + } + docombine = true + + # Set rejection algorithm specific parameters + switch (reject) { + case CCDCLIP, CRREJECT: + call salloc (nm, 3*nimages, TY_REAL) + i = 1 + if (ctor (Memc[rdnoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)] = r + } else { + do i = 1, nimages + Memr[nm+3*(i-1)] = imgetr (in[i], Memc[rdnoise]) + } + i = 1 + if (ctor (Memc[gain], i, r) > 0) { + do i = 1, nimages { + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[gain]) + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } + i = 1 + if (ctor (Memc[snoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)+2] = r + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[snoise]) + Memr[nm+3*(i-1)+2] = r + } + } + if (!keepids) { + if (doscale1) + keepids = true + else { + do i = 2, nimages { + if (Memr[nm+3*(i-1)] != Memr[nm] || + Memr[nm+3*(i-1)+1] != Memr[nm+1] || + Memr[nm+3*(i-1)+2] != Memr[nm+2]) { + keepids = true + break + } + } + } + } + if (reject == CRREJECT) + lsigma = MAX_REAL + case MINMAX: + mclip = false + case PCLIP: + mclip = true + case AVSIGCLIP, SIGCLIP: + if (doscale1) + keepids = true + case NONE: + mclip = false + } + + if (out[4] != NULL) + keepids = true + + if (grow >= 1.) { + keepids = true + call salloc (work, npts * nimages, TY_INT) + } + pms = NULL + + if (keepids) { + do i = 1, nimages + call salloc (id[i], npts, TY_INT) + } + + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatai (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclipi (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + else + call ic_accdclipi (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + case MINMAX: + call ic_mmi (d, id, n, npts) + case PCLIP: + call ic_pclipi (d, id, n, nimages, npts, Memr[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclipi (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + else + call ic_asigclipi (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclipi (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + else + call ic_aavsigclipi (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_averagei (d, id, n, wts, npts, YES, + Memr[outdata]) + case MEDIAN: + call ic_mediani (d, n, npts, YES, Memr[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmai (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + if (pms != NULL) { + if (nkeep > 0) { + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call imunmap (out[1]) + iferr (buf = immap (Memc[fname], READ_WRITE, 0)) { + switch (errcode()) { + case SYS_FXFOPNOEXTNV: + call imgcluster (Memc[fname], Memc[fname], SZ_FNAME) + ext = ext + 1 + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext) + iferr (buf = immap (Memc[imname], READ_WRITE, 0)) { + buf = NULL + ext = 0 + } + repeat { + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext+1) + iferr (outdata = immap (Memc[imname],READ_WRITE,0)) + break + if (buf != NULL) + call imunmap (buf) + buf = outdata + ext = ext + 1 + } + default: + call erract (EA_ERROR) + } + } + out[1] = buf + } + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatai (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_growi (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnlr (out[1], buf, Meml[v1]) == EOF) + ; + call amovr (Memr[buf], Memr[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_averagei (d, id, n, wts, npts, NO, Memr[outdata]) + case MEDIAN: + call ic_mediani (d, n, npts, NO, Memr[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmai (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + do i = 1, nimages + call pm_close (Memi[pms+i-1]) + call mfree (pms, TY_POINTER) + } + + call sfree (sp) +end + +procedure icombiner (in, out, offsets, nimages, bufsize) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int offsets[nimages,ARB] # Input image offsets +int nimages # Number of input images +int bufsize # IMIO buffer size + +char str[1] +int i, j, npts, fd, stropen(), errcode(), imstati() +pointer sp, d, id, n, m, lflag, scales, zeros, wts, dbuf +pointer buf, imgl1r(), impl1i() +errchk stropen, imgl1r, impl1i +pointer impl1r() +errchk impl1r + +include "../icombine.com" + +begin + npts = IM_LEN(out[1],1) + + # Allocate memory. + call smark (sp) + call salloc (dbuf, nimages, TY_POINTER) + call salloc (d, nimages, TY_POINTER) + call salloc (id, nimages, TY_POINTER) + call salloc (n, npts, TY_INT) + call salloc (m, nimages, TY_POINTER) + call salloc (lflag, nimages, TY_INT) + call salloc (scales, nimages, TY_REAL) + call salloc (zeros, nimages, TY_REAL) + call salloc (wts, nimages, TY_REAL) + call amovki (D_ALL, Memi[lflag], nimages) + + # If not aligned or growing create data buffers of output length + # otherwise use the IMIO buffers. + + if (!aligned || grow >= 1.) { + do i = 1, nimages + call salloc (Memi[dbuf+i-1], npts, TY_REAL) + } else + call amovki (NULL, Memi[dbuf], nimages) + + if (project) { + call imseti (in[1], IM_NBUFS, nimages) + call imseti (in[1], IM_BUFSIZE, bufsize) + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + } else { + # Reserve FD for string operations. + fd = stropen (str, 1, NEW_FILE) + + # Do I/O to the images. + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + buf = impl1r (out[1]) + call aclrr (Memr[buf], npts) + if (out[3] != NULL) { + buf = impl1r (out[3]) + call aclrr (Memr[buf], npts) + } + if (out[2] != NULL) { + buf = impl1i (out[2]) + call aclri (Memi[buf], npts) + } + + do i = 1, nimages { + call imseti (in[i], IM_BUFSIZE, bufsize) + iferr (buf = imgl1r (in[i])) { + switch (errcode()) { + case SYS_MFULL: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + case SYS_FTOOMANYFILES, SYS_IKIOPIX: + if (imstati (in[i], IM_CLOSEFD) == YES) { + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + do j = i-2, nimages + call imseti (in[j], IM_CLOSEFD, YES) + buf = imgl1r (in[i]) + default: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + } + } + + call strclose (fd) + } + + call ic_combiner (in, out, Memi[dbuf], Memi[d], Memi[id], Memi[n], + Memi[m], Memi[lflag], offsets, Memr[scales], Memr[zeros], + Memr[wts], nimages, npts) +end + + +# IC_COMBINE -- Combine images. + +procedure ic_combiner (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, wts, nimages, npts) + +pointer in[nimages] # Input images +pointer out[4] # Output image +pointer dbuf[nimages] # Data buffers for nonaligned images +pointer d[nimages] # Data pointers +pointer id[nimages] # Image index ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Line flags +int offsets[nimages,ARB] # Input image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +real wts[nimages] # Combining weights +int nimages # Number of input images +int npts # Number of points per output line + +int i, ext, ctor(), ic_qsort(), errcode() +real r, imgetr() +pointer sp, fname, imname, v1, v2, v3, work +pointer outdata, buf, nm, pms +pointer immap(), impnli() +pointer impnlr(), imgnlr +errchk immap, ic_scale, imgetr, ic_grow, ic_growr, ic_rmasks +extern ic_qsort + +include "../icombine.com" +data ext/0/ + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (imname, SZ_FNAME, TY_CHAR) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (v3, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + + call ic_scale (in, out, offsets, scales, zeros, wts, nimages) + + # Set combine parameters + switch (combine) { + case AVERAGE: + if (dowts) + keepids = true + else + keepids = false + case MEDIAN: + dowts = false + keepids = false + } + docombine = true + + # Set rejection algorithm specific parameters + switch (reject) { + case CCDCLIP, CRREJECT: + call salloc (nm, 3*nimages, TY_REAL) + i = 1 + if (ctor (Memc[rdnoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)] = r + } else { + do i = 1, nimages + Memr[nm+3*(i-1)] = imgetr (in[i], Memc[rdnoise]) + } + i = 1 + if (ctor (Memc[gain], i, r) > 0) { + do i = 1, nimages { + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[gain]) + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } + i = 1 + if (ctor (Memc[snoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)+2] = r + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[snoise]) + Memr[nm+3*(i-1)+2] = r + } + } + if (!keepids) { + if (doscale1) + keepids = true + else { + do i = 2, nimages { + if (Memr[nm+3*(i-1)] != Memr[nm] || + Memr[nm+3*(i-1)+1] != Memr[nm+1] || + Memr[nm+3*(i-1)+2] != Memr[nm+2]) { + keepids = true + break + } + } + } + } + if (reject == CRREJECT) + lsigma = MAX_REAL + case MINMAX: + mclip = false + case PCLIP: + mclip = true + case AVSIGCLIP, SIGCLIP: + if (doscale1) + keepids = true + case NONE: + mclip = false + } + + if (out[4] != NULL) + keepids = true + + if (grow >= 1.) { + keepids = true + call salloc (work, npts * nimages, TY_INT) + } + pms = NULL + + if (keepids) { + do i = 1, nimages + call salloc (id[i], npts, TY_INT) + } + + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatar (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclipr (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + else + call ic_accdclipr (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + case MINMAX: + call ic_mmr (d, id, n, npts) + case PCLIP: + call ic_pclipr (d, id, n, nimages, npts, Memr[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclipr (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + else + call ic_asigclipr (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclipr (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + else + call ic_aavsigclipr (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_averager (d, id, n, wts, npts, YES, + Memr[outdata]) + case MEDIAN: + call ic_medianr (d, n, npts, YES, Memr[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmar (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + if (pms != NULL) { + if (nkeep > 0) { + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call imunmap (out[1]) + iferr (buf = immap (Memc[fname], READ_WRITE, 0)) { + switch (errcode()) { + case SYS_FXFOPNOEXTNV: + call imgcluster (Memc[fname], Memc[fname], SZ_FNAME) + ext = ext + 1 + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext) + iferr (buf = immap (Memc[imname], READ_WRITE, 0)) { + buf = NULL + ext = 0 + } + repeat { + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext+1) + iferr (outdata = immap (Memc[imname],READ_WRITE,0)) + break + if (buf != NULL) + call imunmap (buf) + buf = outdata + ext = ext + 1 + } + default: + call erract (EA_ERROR) + } + } + out[1] = buf + } + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatar (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_growr (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnlr (out[1], buf, Meml[v1]) == EOF) + ; + call amovr (Memr[buf], Memr[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_averager (d, id, n, wts, npts, NO, Memr[outdata]) + case MEDIAN: + call ic_medianr (d, n, npts, NO, Memr[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigmar (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + do i = 1, nimages + call pm_close (Memi[pms+i-1]) + call mfree (pms, TY_POINTER) + } + + call sfree (sp) +end + +procedure icombined (in, out, offsets, nimages, bufsize) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int offsets[nimages,ARB] # Input image offsets +int nimages # Number of input images +int bufsize # IMIO buffer size + +char str[1] +int i, j, npts, fd, stropen(), errcode(), imstati() +pointer sp, d, id, n, m, lflag, scales, zeros, wts, dbuf +pointer buf, imgl1d(), impl1i() +errchk stropen, imgl1d, impl1i +pointer impl1d() +errchk impl1d + +include "../icombine.com" + +begin + npts = IM_LEN(out[1],1) + + # Allocate memory. + call smark (sp) + call salloc (dbuf, nimages, TY_POINTER) + call salloc (d, nimages, TY_POINTER) + call salloc (id, nimages, TY_POINTER) + call salloc (n, npts, TY_INT) + call salloc (m, nimages, TY_POINTER) + call salloc (lflag, nimages, TY_INT) + call salloc (scales, nimages, TY_REAL) + call salloc (zeros, nimages, TY_REAL) + call salloc (wts, nimages, TY_REAL) + call amovki (D_ALL, Memi[lflag], nimages) + + # If not aligned or growing create data buffers of output length + # otherwise use the IMIO buffers. + + if (!aligned || grow >= 1.) { + do i = 1, nimages + call salloc (Memi[dbuf+i-1], npts, TY_DOUBLE) + } else + call amovki (NULL, Memi[dbuf], nimages) + + if (project) { + call imseti (in[1], IM_NBUFS, nimages) + call imseti (in[1], IM_BUFSIZE, bufsize) + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + } else { + # Reserve FD for string operations. + fd = stropen (str, 1, NEW_FILE) + + # Do I/O to the images. + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + buf = impl1d (out[1]) + call aclrd (Memd[buf], npts) + if (out[3] != NULL) { + buf = impl1d (out[3]) + call aclrd (Memd[buf], npts) + } + if (out[2] != NULL) { + buf = impl1i (out[2]) + call aclri (Memi[buf], npts) + } + + do i = 1, nimages { + call imseti (in[i], IM_BUFSIZE, bufsize) + iferr (buf = imgl1d (in[i])) { + switch (errcode()) { + case SYS_MFULL: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + case SYS_FTOOMANYFILES, SYS_IKIOPIX: + if (imstati (in[i], IM_CLOSEFD) == YES) { + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + do j = i-2, nimages + call imseti (in[j], IM_CLOSEFD, YES) + buf = imgl1d (in[i]) + default: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + } + } + + call strclose (fd) + } + + call ic_combined (in, out, Memi[dbuf], Memi[d], Memi[id], Memi[n], + Memi[m], Memi[lflag], offsets, Memr[scales], Memr[zeros], + Memr[wts], nimages, npts) +end + + +# IC_COMBINE -- Combine images. + +procedure ic_combined (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, wts, nimages, npts) + +pointer in[nimages] # Input images +pointer out[4] # Output image +pointer dbuf[nimages] # Data buffers for nonaligned images +pointer d[nimages] # Data pointers +pointer id[nimages] # Image index ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Line flags +int offsets[nimages,ARB] # Input image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +real wts[nimages] # Combining weights +int nimages # Number of input images +int npts # Number of points per output line + +int i, ext, ctor(), ic_qsort(), errcode() +real r, imgetr() +pointer sp, fname, imname, v1, v2, v3, work +pointer outdata, buf, nm, pms +pointer immap(), impnli() +pointer impnld(), imgnld +errchk immap, ic_scale, imgetr, ic_grow, ic_growd, ic_rmasks +extern ic_qsort + +include "../icombine.com" +data ext/0/ + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (imname, SZ_FNAME, TY_CHAR) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (v3, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + + call ic_scale (in, out, offsets, scales, zeros, wts, nimages) + + # Set combine parameters + switch (combine) { + case AVERAGE: + if (dowts) + keepids = true + else + keepids = false + case MEDIAN: + dowts = false + keepids = false + } + docombine = true + + # Set rejection algorithm specific parameters + switch (reject) { + case CCDCLIP, CRREJECT: + call salloc (nm, 3*nimages, TY_REAL) + i = 1 + if (ctor (Memc[rdnoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)] = r + } else { + do i = 1, nimages + Memr[nm+3*(i-1)] = imgetr (in[i], Memc[rdnoise]) + } + i = 1 + if (ctor (Memc[gain], i, r) > 0) { + do i = 1, nimages { + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[gain]) + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } + i = 1 + if (ctor (Memc[snoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)+2] = r + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[snoise]) + Memr[nm+3*(i-1)+2] = r + } + } + if (!keepids) { + if (doscale1) + keepids = true + else { + do i = 2, nimages { + if (Memr[nm+3*(i-1)] != Memr[nm] || + Memr[nm+3*(i-1)+1] != Memr[nm+1] || + Memr[nm+3*(i-1)+2] != Memr[nm+2]) { + keepids = true + break + } + } + } + } + if (reject == CRREJECT) + lsigma = MAX_REAL + case MINMAX: + mclip = false + case PCLIP: + mclip = true + case AVSIGCLIP, SIGCLIP: + if (doscale1) + keepids = true + case NONE: + mclip = false + } + + if (out[4] != NULL) + keepids = true + + if (grow >= 1.) { + keepids = true + call salloc (work, npts * nimages, TY_INT) + } + pms = NULL + + if (keepids) { + do i = 1, nimages + call salloc (id[i], npts, TY_INT) + } + + while (impnld (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatad (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclipd (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memd[outdata]) + else + call ic_accdclipd (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memd[outdata]) + case MINMAX: + call ic_mmd (d, id, n, npts) + case PCLIP: + call ic_pclipd (d, id, n, nimages, npts, Memd[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclipd (d, id, n, scales, zeros, nimages, npts, + Memd[outdata]) + else + call ic_asigclipd (d, id, n, scales, zeros, nimages, npts, + Memd[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclipd (d, id, n, scales, zeros, nimages, + npts, Memd[outdata]) + else + call ic_aavsigclipd (d, id, n, scales, zeros, nimages, + npts, Memd[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_averaged (d, id, n, wts, npts, YES, + Memd[outdata]) + case MEDIAN: + call ic_mediand (d, n, npts, YES, Memd[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnld (out[3], buf, Meml[v1]) + call ic_sigmad (d, id, n, wts, npts, Memd[outdata], + Memd[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + if (pms != NULL) { + if (nkeep > 0) { + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call imunmap (out[1]) + iferr (buf = immap (Memc[fname], READ_WRITE, 0)) { + switch (errcode()) { + case SYS_FXFOPNOEXTNV: + call imgcluster (Memc[fname], Memc[fname], SZ_FNAME) + ext = ext + 1 + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext) + iferr (buf = immap (Memc[imname], READ_WRITE, 0)) { + buf = NULL + ext = 0 + } + repeat { + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext+1) + iferr (outdata = immap (Memc[imname],READ_WRITE,0)) + break + if (buf != NULL) + call imunmap (buf) + buf = outdata + ext = ext + 1 + } + default: + call erract (EA_ERROR) + } + } + out[1] = buf + } + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + while (impnld (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdatad (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_growd (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnld (out[1], buf, Meml[v1]) == EOF) + ; + call amovd (Memd[buf], Memd[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_averaged (d, id, n, wts, npts, NO, Memd[outdata]) + case MEDIAN: + call ic_mediand (d, n, npts, NO, Memd[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnld (out[3], buf, Meml[v1]) + call ic_sigmad (d, id, n, wts, npts, Memd[outdata], + Memd[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + + do i = 1, nimages + call pm_close (Memi[pms+i-1]) + call mfree (pms, TY_POINTER) + } + + call sfree (sp) +end + + + +# IC_QSORT -- Compare line numbers for GQSORT. + +int procedure ic_qsort (arg, i1, i2) + +pointer arg +int i1, i2 + +begin + if (Mems[arg+i1-1] < Mems[arg+i2-1]) + return (-1) + else if (Mems[arg+i1-1] > Mems[arg+i2-1]) + return (1) + else + return (0) +end diff --git a/pkg/obsolete/imcombine/generic/icpclip.x b/pkg/obsolete/imcombine/generic/icpclip.x new file mode 100644 index 00000000..237d9686 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icpclip.x @@ -0,0 +1,878 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Minimum number for clipping + + +# IC_PCLIP -- Percentile clip +# +# 1) Find the median +# 2) Find the pixel which is the specified order index away +# 3) Use the data value difference as a sigma and apply clipping +# 4) Since the median is known return it so it does not have to be recomputed + +procedure ic_pclips (d, m, n, nimages, npts, median) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[npts] # Number of good pixels +int nimages # Number of input images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, n4, n5, nl, nh, nin, maxkeep +bool even, fp_equalr() +real sigma, r, s, t +pointer sp, resid, mp1, mp2 +real med + +include "../icombine.com" + +begin + # There must be at least MINCLIP and more than nkeep pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Set sign of pclip parameter + if (pclip < 0) + t = -1. + else + t = 1. + + # If there are no rejected pixels compute certain parameters once. + if (dflag == D_ALL) { + n1 = n[1] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0.) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + nin = n1 + } + + # Now apply clipping. + do i = 1, npts { + # Compute median. + if (dflag == D_MIX) { + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 == 0) { + if (combine == MEDIAN) + median[i] = blank + next + } + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + } + + j = i - 1 + if (even) { + med = Mems[d[n2-1]+j] + med = (med + Mems[d[n2]+j]) / 2. + } else + med = Mems[d[n2]+j] + + if (n1 < max (MINCLIP, maxkeep+1)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Define sigma for clipping + sigma = t * (Mems[d[n3]+j] - med) + if (fp_equalr (sigma, 0.)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Reject pixels and save residuals. + # Check if any pixels are clipped. + # If so recompute the median and reset the number of good pixels. + # Only reorder if needed. + + for (nl=1; nl<=n1; nl=nl+1) { + r = (med - Mems[d[nl]+j]) / sigma + if (r < lsigma) + break + Memr[resid+nl] = r + } + for (nh=n1; nh>=1; nh=nh-1) { + r = (Mems[d[nh]+j] - med) / sigma + if (r < hsigma) + break + Memr[resid+nh] = r + } + n4 = nh - nl + 1 + + # If too many pixels are rejected add some back in. + # All pixels with the same residual are added. + while (n4 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n4 = nh - nl + 1 + } + + # If any pixels are rejected recompute the median. + if (nl > 1 || nh < n1) { + n5 = nl + n4 / 2 + if (mod (n4, 2) == 0) { + med = Mems[d[n5-1]+j] + med = (med + Mems[d[n5]+j]) / 2. + } else + med = Mems[d[n5]+j] + n[i] = n4 + } + if (combine == MEDIAN) + median[i] = med + + # Reorder if pixels only if necessary. + if (nl > 1 && (combine != MEDIAN || grow >= 1.)) { + k = max (nl, n4 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mems[d[l]+j] = Mems[d[k]+j] + if (grow >= 1.) { + mp1 = m[l] + j + mp2 = m[k] + j + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+j] = Memi[m[k]+j] + k = k + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mems[d[l]+j] = Mems[d[k]+j] + k = k + 1 + } + } + } + } + + # Check if data flag needs to be reset for rejected pixels. + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag whether the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_PCLIP -- Percentile clip +# +# 1) Find the median +# 2) Find the pixel which is the specified order index away +# 3) Use the data value difference as a sigma and apply clipping +# 4) Since the median is known return it so it does not have to be recomputed + +procedure ic_pclipi (d, m, n, nimages, npts, median) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[npts] # Number of good pixels +int nimages # Number of input images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, n4, n5, nl, nh, nin, maxkeep +bool even, fp_equalr() +real sigma, r, s, t +pointer sp, resid, mp1, mp2 +real med + +include "../icombine.com" + +begin + # There must be at least MINCLIP and more than nkeep pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Set sign of pclip parameter + if (pclip < 0) + t = -1. + else + t = 1. + + # If there are no rejected pixels compute certain parameters once. + if (dflag == D_ALL) { + n1 = n[1] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0.) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + nin = n1 + } + + # Now apply clipping. + do i = 1, npts { + # Compute median. + if (dflag == D_MIX) { + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 == 0) { + if (combine == MEDIAN) + median[i] = blank + next + } + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + } + + j = i - 1 + if (even) { + med = Memi[d[n2-1]+j] + med = (med + Memi[d[n2]+j]) / 2. + } else + med = Memi[d[n2]+j] + + if (n1 < max (MINCLIP, maxkeep+1)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Define sigma for clipping + sigma = t * (Memi[d[n3]+j] - med) + if (fp_equalr (sigma, 0.)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Reject pixels and save residuals. + # Check if any pixels are clipped. + # If so recompute the median and reset the number of good pixels. + # Only reorder if needed. + + for (nl=1; nl<=n1; nl=nl+1) { + r = (med - Memi[d[nl]+j]) / sigma + if (r < lsigma) + break + Memr[resid+nl] = r + } + for (nh=n1; nh>=1; nh=nh-1) { + r = (Memi[d[nh]+j] - med) / sigma + if (r < hsigma) + break + Memr[resid+nh] = r + } + n4 = nh - nl + 1 + + # If too many pixels are rejected add some back in. + # All pixels with the same residual are added. + while (n4 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n4 = nh - nl + 1 + } + + # If any pixels are rejected recompute the median. + if (nl > 1 || nh < n1) { + n5 = nl + n4 / 2 + if (mod (n4, 2) == 0) { + med = Memi[d[n5-1]+j] + med = (med + Memi[d[n5]+j]) / 2. + } else + med = Memi[d[n5]+j] + n[i] = n4 + } + if (combine == MEDIAN) + median[i] = med + + # Reorder if pixels only if necessary. + if (nl > 1 && (combine != MEDIAN || grow >= 1.)) { + k = max (nl, n4 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memi[d[l]+j] = Memi[d[k]+j] + if (grow >= 1.) { + mp1 = m[l] + j + mp2 = m[k] + j + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+j] = Memi[m[k]+j] + k = k + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memi[d[l]+j] = Memi[d[k]+j] + k = k + 1 + } + } + } + } + + # Check if data flag needs to be reset for rejected pixels. + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag whether the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_PCLIP -- Percentile clip +# +# 1) Find the median +# 2) Find the pixel which is the specified order index away +# 3) Use the data value difference as a sigma and apply clipping +# 4) Since the median is known return it so it does not have to be recomputed + +procedure ic_pclipr (d, m, n, nimages, npts, median) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[npts] # Number of good pixels +int nimages # Number of input images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, n4, n5, nl, nh, nin, maxkeep +bool even, fp_equalr() +real sigma, r, s, t +pointer sp, resid, mp1, mp2 +real med + +include "../icombine.com" + +begin + # There must be at least MINCLIP and more than nkeep pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Set sign of pclip parameter + if (pclip < 0) + t = -1. + else + t = 1. + + # If there are no rejected pixels compute certain parameters once. + if (dflag == D_ALL) { + n1 = n[1] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0.) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + nin = n1 + } + + # Now apply clipping. + do i = 1, npts { + # Compute median. + if (dflag == D_MIX) { + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 == 0) { + if (combine == MEDIAN) + median[i] = blank + next + } + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + } + + j = i - 1 + if (even) { + med = Memr[d[n2-1]+j] + med = (med + Memr[d[n2]+j]) / 2. + } else + med = Memr[d[n2]+j] + + if (n1 < max (MINCLIP, maxkeep+1)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Define sigma for clipping + sigma = t * (Memr[d[n3]+j] - med) + if (fp_equalr (sigma, 0.)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Reject pixels and save residuals. + # Check if any pixels are clipped. + # If so recompute the median and reset the number of good pixels. + # Only reorder if needed. + + for (nl=1; nl<=n1; nl=nl+1) { + r = (med - Memr[d[nl]+j]) / sigma + if (r < lsigma) + break + Memr[resid+nl] = r + } + for (nh=n1; nh>=1; nh=nh-1) { + r = (Memr[d[nh]+j] - med) / sigma + if (r < hsigma) + break + Memr[resid+nh] = r + } + n4 = nh - nl + 1 + + # If too many pixels are rejected add some back in. + # All pixels with the same residual are added. + while (n4 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n4 = nh - nl + 1 + } + + # If any pixels are rejected recompute the median. + if (nl > 1 || nh < n1) { + n5 = nl + n4 / 2 + if (mod (n4, 2) == 0) { + med = Memr[d[n5-1]+j] + med = (med + Memr[d[n5]+j]) / 2. + } else + med = Memr[d[n5]+j] + n[i] = n4 + } + if (combine == MEDIAN) + median[i] = med + + # Reorder if pixels only if necessary. + if (nl > 1 && (combine != MEDIAN || grow >= 1.)) { + k = max (nl, n4 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memr[d[l]+j] = Memr[d[k]+j] + if (grow >= 1.) { + mp1 = m[l] + j + mp2 = m[k] + j + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+j] = Memi[m[k]+j] + k = k + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memr[d[l]+j] = Memr[d[k]+j] + k = k + 1 + } + } + } + } + + # Check if data flag needs to be reset for rejected pixels. + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag whether the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_PCLIP -- Percentile clip +# +# 1) Find the median +# 2) Find the pixel which is the specified order index away +# 3) Use the data value difference as a sigma and apply clipping +# 4) Since the median is known return it so it does not have to be recomputed + +procedure ic_pclipd (d, m, n, nimages, npts, median) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[npts] # Number of good pixels +int nimages # Number of input images +int npts # Number of output points per line +double median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, n4, n5, nl, nh, nin, maxkeep +bool even, fp_equalr() +real sigma, r, s, t +pointer sp, resid, mp1, mp2 +double med + +include "../icombine.com" + +begin + # There must be at least MINCLIP and more than nkeep pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Set sign of pclip parameter + if (pclip < 0) + t = -1. + else + t = 1. + + # If there are no rejected pixels compute certain parameters once. + if (dflag == D_ALL) { + n1 = n[1] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0.) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + nin = n1 + } + + # Now apply clipping. + do i = 1, npts { + # Compute median. + if (dflag == D_MIX) { + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 == 0) { + if (combine == MEDIAN) + median[i] = blank + next + } + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + } + + j = i - 1 + if (even) { + med = Memd[d[n2-1]+j] + med = (med + Memd[d[n2]+j]) / 2. + } else + med = Memd[d[n2]+j] + + if (n1 < max (MINCLIP, maxkeep+1)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Define sigma for clipping + sigma = t * (Memd[d[n3]+j] - med) + if (fp_equalr (sigma, 0.)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Reject pixels and save residuals. + # Check if any pixels are clipped. + # If so recompute the median and reset the number of good pixels. + # Only reorder if needed. + + for (nl=1; nl<=n1; nl=nl+1) { + r = (med - Memd[d[nl]+j]) / sigma + if (r < lsigma) + break + Memr[resid+nl] = r + } + for (nh=n1; nh>=1; nh=nh-1) { + r = (Memd[d[nh]+j] - med) / sigma + if (r < hsigma) + break + Memr[resid+nh] = r + } + n4 = nh - nl + 1 + + # If too many pixels are rejected add some back in. + # All pixels with the same residual are added. + while (n4 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n4 = nh - nl + 1 + } + + # If any pixels are rejected recompute the median. + if (nl > 1 || nh < n1) { + n5 = nl + n4 / 2 + if (mod (n4, 2) == 0) { + med = Memd[d[n5-1]+j] + med = (med + Memd[d[n5]+j]) / 2. + } else + med = Memd[d[n5]+j] + n[i] = n4 + } + if (combine == MEDIAN) + median[i] = med + + # Reorder if pixels only if necessary. + if (nl > 1 && (combine != MEDIAN || grow >= 1.)) { + k = max (nl, n4 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memd[d[l]+j] = Memd[d[k]+j] + if (grow >= 1.) { + mp1 = m[l] + j + mp2 = m[k] + j + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+j] = Memi[m[k]+j] + k = k + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memd[d[l]+j] = Memd[d[k]+j] + k = k + 1 + } + } + } + } + + # Check if data flag needs to be reset for rejected pixels. + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag whether the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/generic/icsclip.x b/pkg/obsolete/imcombine/generic/icsclip.x new file mode 100644 index 00000000..a0188d72 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icsclip.x @@ -0,0 +1,1922 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Mininum number of images for algorithm + + +# IC_ASIGCLIP -- Reject pixels using sigma clipping about the average +# The initial average rejects the high and low pixels. A correction for +# different scalings of the images may be made. Weights are not used. + +procedure ic_asigclips (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, one +data one /1.0/ +pointer sp, resid, w, wp, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Flag whether returned average needs to be recomputed. + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Save the residuals and the sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Do sigma clipping. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + + # If there are not enough pixels simply compute the average. + if (n1 < max (3, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mems[d[1]+k] + do j = 2, n1 + sum = sum + Mems[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + # Compute average with the high and low rejected. + low = Mems[d[1]+k] + high = Mems[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mems[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Iteratively reject pixels and compute the final average if needed. + # Compact the data and keep track of the image IDs if needed. + + repeat { + n2 = n1 + if (doscale1) { + # Compute sigma corrected for scaling. + s = 0. + wp = w - 1 + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Mems[dp1] + l = Memi[mp1] + r = sqrt (max (one, (a + zeros[l]) / scales[l])) + s = s + ((d1 - a) / r) ** 2 + Memr[wp] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + wp = w - 1 + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Mems[dp1] + r = (d1 - a) / (s * Memr[wp]) + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + Memr[wp] = Memr[w+n1-1] + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } else { + # Compute the sigma without scale correction. + s = 0. + do j = 1, n1 + s = s + (Mems[d[j]+k] - a) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Mems[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mems[dp1] + Mems[dp1] = Mems[dp2] + Mems[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mems[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MSIGCLIP -- Reject pixels using sigma clipping about the median + +procedure ic_msigclips (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, w, mp1, mp2 +real med, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Save the residuals and sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) + med = (Mems[d[n3-1]+k] + Mems[d[n3]+k]) / 2. + else + med = Mems[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + # Compute the sigma with scaling correction. + s = 0. + do j = nl, nh { + l = Memi[m[j]+k] + r = sqrt (max (one, (med + zeros[l]) / scales[l])) + s = s + ((Mems[d[j]+k] - med) / r) ** 2 + Memr[w+j-1] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Mems[d[nl]+k]) / (s * Memr[w+nl-1]) + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mems[d[nh]+k] - med) / (s * Memr[w+nh-1]) + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } else { + # Compute the sigma without scaling correction. + s = 0. + do j = nl, nh + s = s + (Mems[d[j]+k] - med) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Mems[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mems[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mems[d[l]+k] = Mems[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mems[d[l]+k] = Mems[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ASIGCLIP -- Reject pixels using sigma clipping about the average +# The initial average rejects the high and low pixels. A correction for +# different scalings of the images may be made. Weights are not used. + +procedure ic_asigclipi (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, one +data one /1.0/ +pointer sp, resid, w, wp, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Flag whether returned average needs to be recomputed. + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Save the residuals and the sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Do sigma clipping. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + + # If there are not enough pixels simply compute the average. + if (n1 < max (3, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memi[d[1]+k] + do j = 2, n1 + sum = sum + Memi[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + # Compute average with the high and low rejected. + low = Memi[d[1]+k] + high = Memi[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memi[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Iteratively reject pixels and compute the final average if needed. + # Compact the data and keep track of the image IDs if needed. + + repeat { + n2 = n1 + if (doscale1) { + # Compute sigma corrected for scaling. + s = 0. + wp = w - 1 + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memi[dp1] + l = Memi[mp1] + r = sqrt (max (one, (a + zeros[l]) / scales[l])) + s = s + ((d1 - a) / r) ** 2 + Memr[wp] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + wp = w - 1 + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memi[dp1] + r = (d1 - a) / (s * Memr[wp]) + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + Memr[wp] = Memr[w+n1-1] + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } else { + # Compute the sigma without scale correction. + s = 0. + do j = 1, n1 + s = s + (Memi[d[j]+k] - a) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memi[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memi[dp1] + Memi[dp1] = Memi[dp2] + Memi[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memi[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MSIGCLIP -- Reject pixels using sigma clipping about the median + +procedure ic_msigclipi (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, w, mp1, mp2 +real med, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Save the residuals and sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) + med = (Memi[d[n3-1]+k] + Memi[d[n3]+k]) / 2. + else + med = Memi[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + # Compute the sigma with scaling correction. + s = 0. + do j = nl, nh { + l = Memi[m[j]+k] + r = sqrt (max (one, (med + zeros[l]) / scales[l])) + s = s + ((Memi[d[j]+k] - med) / r) ** 2 + Memr[w+j-1] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memi[d[nl]+k]) / (s * Memr[w+nl-1]) + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memi[d[nh]+k] - med) / (s * Memr[w+nh-1]) + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } else { + # Compute the sigma without scaling correction. + s = 0. + do j = nl, nh + s = s + (Memi[d[j]+k] - med) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memi[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memi[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memi[d[l]+k] = Memi[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memi[d[l]+k] = Memi[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ASIGCLIP -- Reject pixels using sigma clipping about the average +# The initial average rejects the high and low pixels. A correction for +# different scalings of the images may be made. Weights are not used. + +procedure ic_asigclipr (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +real d1, low, high, sum, a, s, r, one +data one /1.0/ +pointer sp, resid, w, wp, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Flag whether returned average needs to be recomputed. + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Save the residuals and the sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Do sigma clipping. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + + # If there are not enough pixels simply compute the average. + if (n1 < max (3, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memr[d[1]+k] + do j = 2, n1 + sum = sum + Memr[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + # Compute average with the high and low rejected. + low = Memr[d[1]+k] + high = Memr[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memr[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Iteratively reject pixels and compute the final average if needed. + # Compact the data and keep track of the image IDs if needed. + + repeat { + n2 = n1 + if (doscale1) { + # Compute sigma corrected for scaling. + s = 0. + wp = w - 1 + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memr[dp1] + l = Memi[mp1] + r = sqrt (max (one, (a + zeros[l]) / scales[l])) + s = s + ((d1 - a) / r) ** 2 + Memr[wp] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + wp = w - 1 + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memr[dp1] + r = (d1 - a) / (s * Memr[wp]) + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + Memr[wp] = Memr[w+n1-1] + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } else { + # Compute the sigma without scale correction. + s = 0. + do j = 1, n1 + s = s + (Memr[d[j]+k] - a) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memr[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memr[dp1] + Memr[dp1] = Memr[dp2] + Memr[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memr[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MSIGCLIP -- Reject pixels using sigma clipping about the median + +procedure ic_msigclipr (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +real median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, w, mp1, mp2 +real med, one +data one /1.0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Save the residuals and sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) + med = (Memr[d[n3-1]+k] + Memr[d[n3]+k]) / 2. + else + med = Memr[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + # Compute the sigma with scaling correction. + s = 0. + do j = nl, nh { + l = Memi[m[j]+k] + r = sqrt (max (one, (med + zeros[l]) / scales[l])) + s = s + ((Memr[d[j]+k] - med) / r) ** 2 + Memr[w+j-1] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memr[d[nl]+k]) / (s * Memr[w+nl-1]) + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memr[d[nh]+k] - med) / (s * Memr[w+nh-1]) + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } else { + # Compute the sigma without scaling correction. + s = 0. + do j = nl, nh + s = s + (Memr[d[j]+k] - med) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memr[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memr[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memr[d[l]+k] = Memr[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memr[d[l]+k] = Memr[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end + +# IC_ASIGCLIP -- Reject pixels using sigma clipping about the average +# The initial average rejects the high and low pixels. A correction for +# different scalings of the images may be made. Weights are not used. + +procedure ic_asigclipd (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +double average[npts] # Average + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +double d1, low, high, sum, a, s, r, one +data one /1.0D0/ +pointer sp, resid, w, wp, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Flag whether returned average needs to be recomputed. + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Save the residuals and the sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Do sigma clipping. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + + # If there are not enough pixels simply compute the average. + if (n1 < max (3, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Memd[d[1]+k] + do j = 2, n1 + sum = sum + Memd[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + # Compute average with the high and low rejected. + low = Memd[d[1]+k] + high = Memd[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Memd[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Iteratively reject pixels and compute the final average if needed. + # Compact the data and keep track of the image IDs if needed. + + repeat { + n2 = n1 + if (doscale1) { + # Compute sigma corrected for scaling. + s = 0. + wp = w - 1 + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memd[dp1] + l = Memi[mp1] + r = sqrt (max (one, (a + zeros[l]) / scales[l])) + s = s + ((d1 - a) / r) ** 2 + Memr[wp] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + wp = w - 1 + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Memd[dp1] + r = (d1 - a) / (s * Memr[wp]) + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + Memr[wp] = Memr[w+n1-1] + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } else { + # Compute the sigma without scale correction. + s = 0. + do j = 1, n1 + s = s + (Memd[d[j]+k] - a) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Memd[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Memd[dp1] + Memd[dp1] = Memd[dp2] + Memd[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Memd[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MSIGCLIP -- Reject pixels using sigma clipping about the median + +procedure ic_msigclipd (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +double median[npts] # Median + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, w, mp1, mp2 +double med, one +data one /1.0D0/ + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Save the residuals and sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) + med = (Memd[d[n3-1]+k] + Memd[d[n3]+k]) / 2. + else + med = Memd[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + # Compute the sigma with scaling correction. + s = 0. + do j = nl, nh { + l = Memi[m[j]+k] + r = sqrt (max (one, (med + zeros[l]) / scales[l])) + s = s + ((Memd[d[j]+k] - med) / r) ** 2 + Memr[w+j-1] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memd[d[nl]+k]) / (s * Memr[w+nl-1]) + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memd[d[nh]+k] - med) / (s * Memr[w+nh-1]) + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } else { + # Compute the sigma without scaling correction. + s = 0. + do j = nl, nh + s = s + (Memd[d[j]+k] - med) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Memd[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Memd[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Memd[d[l]+k] = Memd[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Memd[d[l]+k] = Memd[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/generic/icsigma.x b/pkg/obsolete/imcombine/generic/icsigma.x new file mode 100644 index 00000000..faf31602 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icsigma.x @@ -0,0 +1,405 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + + +# IC_SIGMA -- Compute the sigma image line. +# The estimated sigma includes a correction for the finite population. +# Weights are used if desired. + +procedure ic_sigmas (d, m, n, wts, npts, average, sigma) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +real average[npts] # Average +real sigma[npts] # Sigma line (returned) + +int i, j, k, n1 +real wt, sigcor, sumwt +real a, sum + +include "../icombine.com" + +begin + if (dflag == D_ALL) { + n1 = n[1] + if (dowts) { + if (n1 > 1) + sigcor = real (n1) / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Mems[d[1]+k] - a) ** 2 * wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Mems[d[j]+k] - a) ** 2 * wt + } + sigma[i] = sqrt (sum * sigcor) + } + } else { + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + sum = (Mems[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Mems[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } + } + } else if (dflag == D_NONE) { + do i = 1, npts + sigma[i] = blank + } else { + if (dowts) { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = real (n1) / real (n1 -1) + else + sigcor = 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Mems[d[1]+k] - a) ** 2 * wt + sumwt = wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Mems[d[j]+k] - a) ** 2 * wt + sumwt = sumwt + wt + } + sigma[i] = sqrt (sum / sumwt * sigcor) + } else + sigma[i] = blank + } + } else { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + a = average[i] + sum = (Mems[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Mems[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } else + sigma[i] = blank + } + } + } +end + +# IC_SIGMA -- Compute the sigma image line. +# The estimated sigma includes a correction for the finite population. +# Weights are used if desired. + +procedure ic_sigmai (d, m, n, wts, npts, average, sigma) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +real average[npts] # Average +real sigma[npts] # Sigma line (returned) + +int i, j, k, n1 +real wt, sigcor, sumwt +real a, sum + +include "../icombine.com" + +begin + if (dflag == D_ALL) { + n1 = n[1] + if (dowts) { + if (n1 > 1) + sigcor = real (n1) / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memi[d[1]+k] - a) ** 2 * wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memi[d[j]+k] - a) ** 2 * wt + } + sigma[i] = sqrt (sum * sigcor) + } + } else { + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + sum = (Memi[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memi[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } + } + } else if (dflag == D_NONE) { + do i = 1, npts + sigma[i] = blank + } else { + if (dowts) { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = real (n1) / real (n1 -1) + else + sigcor = 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memi[d[1]+k] - a) ** 2 * wt + sumwt = wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memi[d[j]+k] - a) ** 2 * wt + sumwt = sumwt + wt + } + sigma[i] = sqrt (sum / sumwt * sigcor) + } else + sigma[i] = blank + } + } else { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + a = average[i] + sum = (Memi[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memi[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } else + sigma[i] = blank + } + } + } +end + +# IC_SIGMA -- Compute the sigma image line. +# The estimated sigma includes a correction for the finite population. +# Weights are used if desired. + +procedure ic_sigmar (d, m, n, wts, npts, average, sigma) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +real average[npts] # Average +real sigma[npts] # Sigma line (returned) + +int i, j, k, n1 +real wt, sigcor, sumwt +real a, sum + +include "../icombine.com" + +begin + if (dflag == D_ALL) { + n1 = n[1] + if (dowts) { + if (n1 > 1) + sigcor = real (n1) / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memr[d[1]+k] - a) ** 2 * wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memr[d[j]+k] - a) ** 2 * wt + } + sigma[i] = sqrt (sum * sigcor) + } + } else { + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + sum = (Memr[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memr[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } + } + } else if (dflag == D_NONE) { + do i = 1, npts + sigma[i] = blank + } else { + if (dowts) { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = real (n1) / real (n1 -1) + else + sigcor = 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memr[d[1]+k] - a) ** 2 * wt + sumwt = wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memr[d[j]+k] - a) ** 2 * wt + sumwt = sumwt + wt + } + sigma[i] = sqrt (sum / sumwt * sigcor) + } else + sigma[i] = blank + } + } else { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + a = average[i] + sum = (Memr[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memr[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } else + sigma[i] = blank + } + } + } +end + +# IC_SIGMA -- Compute the sigma image line. +# The estimated sigma includes a correction for the finite population. +# Weights are used if desired. + +procedure ic_sigmad (d, m, n, wts, npts, average, sigma) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +double average[npts] # Average +double sigma[npts] # Sigma line (returned) + +int i, j, k, n1 +real wt, sigcor, sumwt +double a, sum + +include "../icombine.com" + +begin + if (dflag == D_ALL) { + n1 = n[1] + if (dowts) { + if (n1 > 1) + sigcor = real (n1) / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memd[d[1]+k] - a) ** 2 * wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memd[d[j]+k] - a) ** 2 * wt + } + sigma[i] = sqrt (sum * sigcor) + } + } else { + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + sum = (Memd[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memd[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } + } + } else if (dflag == D_NONE) { + do i = 1, npts + sigma[i] = blank + } else { + if (dowts) { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = real (n1) / real (n1 -1) + else + sigcor = 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Memd[d[1]+k] - a) ** 2 * wt + sumwt = wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Memd[d[j]+k] - a) ** 2 * wt + sumwt = sumwt + wt + } + sigma[i] = sqrt (sum / sumwt * sigcor) + } else + sigma[i] = blank + } + } else { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + a = average[i] + sum = (Memd[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Memd[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } else + sigma[i] = blank + } + } + } +end diff --git a/pkg/obsolete/imcombine/generic/icsort.x b/pkg/obsolete/imcombine/generic/icsort.x new file mode 100644 index 00000000..3ec1d27e --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icsort.x @@ -0,0 +1,1096 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +define LOGPTR 32 # log2(maxpts) (4e9) + + +# IC_SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. + +procedure ic_sorts (a, b, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +short b[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +short pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR] +define swap {temp=$1;$1=$2;$2=temp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix + b[i] = Mems[a[i]+l] + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + + # General case + do i = 1, npix + b[i] = Mems[a[i]+l] + + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) # out of order pair + swap (b[i], b[j]) # interchange elements + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix + Mems[a[i]+l] = b[i] + } +end + + +# IC_2SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. A second integer set of +# vectors is sorted. + +procedure ic_2sorts (a, b, c, d, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +short b[ARB] # work array +pointer c[ARB] # pointer to associated integer vectors +int d[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +short pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR], itemp +define swap {temp=$1;$1=$2;$2=temp} +define iswap {itemp=$1;$1=$2;$2=itemp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix { + b[i] = Mems[a[i]+l] + d[i] = Memi[c[i]+l] + } + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + + # General case + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]); swap (d[j], d[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) { # out of order pair + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + } + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix { + Mems[a[i]+l] = b[i] + Memi[c[i]+l] = d[i] + } + } +end + +# IC_SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. + +procedure ic_sorti (a, b, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +int b[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +int pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR] +define swap {temp=$1;$1=$2;$2=temp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix + b[i] = Memi[a[i]+l] + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + + # General case + do i = 1, npix + b[i] = Memi[a[i]+l] + + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) # out of order pair + swap (b[i], b[j]) # interchange elements + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix + Memi[a[i]+l] = b[i] + } +end + + +# IC_2SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. A second integer set of +# vectors is sorted. + +procedure ic_2sorti (a, b, c, d, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +int b[ARB] # work array +pointer c[ARB] # pointer to associated integer vectors +int d[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +int pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR], itemp +define swap {temp=$1;$1=$2;$2=temp} +define iswap {itemp=$1;$1=$2;$2=itemp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix { + b[i] = Memi[a[i]+l] + d[i] = Memi[c[i]+l] + } + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + + # General case + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]); swap (d[j], d[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) { # out of order pair + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + } + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix { + Memi[a[i]+l] = b[i] + Memi[c[i]+l] = d[i] + } + } +end + +# IC_SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. + +procedure ic_sortr (a, b, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +real b[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +real pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR] +define swap {temp=$1;$1=$2;$2=temp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix + b[i] = Memr[a[i]+l] + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + + # General case + do i = 1, npix + b[i] = Memr[a[i]+l] + + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) # out of order pair + swap (b[i], b[j]) # interchange elements + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix + Memr[a[i]+l] = b[i] + } +end + + +# IC_2SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. A second integer set of +# vectors is sorted. + +procedure ic_2sortr (a, b, c, d, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +real b[ARB] # work array +pointer c[ARB] # pointer to associated integer vectors +int d[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +real pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR], itemp +define swap {temp=$1;$1=$2;$2=temp} +define iswap {itemp=$1;$1=$2;$2=itemp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix { + b[i] = Memr[a[i]+l] + d[i] = Memi[c[i]+l] + } + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + + # General case + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]); swap (d[j], d[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) { # out of order pair + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + } + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix { + Memr[a[i]+l] = b[i] + Memi[c[i]+l] = d[i] + } + } +end + +# IC_SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. + +procedure ic_sortd (a, b, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +double b[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +double pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR] +define swap {temp=$1;$1=$2;$2=temp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix + b[i] = Memd[a[i]+l] + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + + # General case + do i = 1, npix + b[i] = Memd[a[i]+l] + + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) # out of order pair + swap (b[i], b[j]) # interchange elements + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix + Memd[a[i]+l] = b[i] + } +end + + +# IC_2SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. A second integer set of +# vectors is sorted. + +procedure ic_2sortd (a, b, c, d, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +double b[ARB] # work array +pointer c[ARB] # pointer to associated integer vectors +int d[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +double pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR], itemp +define swap {temp=$1;$1=$2;$2=temp} +define iswap {itemp=$1;$1=$2;$2=itemp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix { + b[i] = Memd[a[i]+l] + d[i] = Memi[c[i]+l] + } + + # Special cases + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + + # General case + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]); swap (d[j], d[k]) + pivot = b[j] # pivot line + + while (i < j) { + for (i=i+1; b[i] < pivot; i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (b[j] <= pivot) + break + if (i < j) { # out of order pair + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + } + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix { + Memd[a[i]+l] = b[i] + Memi[c[i]+l] = d[i] + } + } +end diff --git a/pkg/obsolete/imcombine/generic/icstat.x b/pkg/obsolete/imcombine/generic/icstat.x new file mode 100644 index 00000000..433f1df5 --- /dev/null +++ b/pkg/obsolete/imcombine/generic/icstat.x @@ -0,0 +1,880 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + +define NMAX 10000 # Maximum number of pixels to sample + + +# IC_STAT -- Compute image statistics within specified section. +# The image section is relative to a reference image which may be +# different than the input image and may have an offset. Only a +# subsample of pixels is used. Masked and thresholded pixels are +# ignored. Only the desired statistics are computed to increase +# efficiency. + +procedure ic_stats (im, imref, section, offsets, image, nimages, + domode, domedian, domean, mode, median, mean) + +pointer im # Data image +pointer imref # Reference image for image section +char section[ARB] # Image section +int offsets[nimages,ARB] # Image section offset from data to reference +int image # Image index (for mask I/O) +int nimages # Number of images in offsets. +bool domode, domedian, domean # Statistics to compute +real mode, median, mean # Statistics + +int i, j, ndim, n, nv +real a +pointer sp, v1, v2, dv, va, vb +pointer data, mask, dp, lp, mp, imgnls() +short ic_modes() +real asums() + + +include "../icombine.com" + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (dv, IM_MAXDIM, TY_LONG) + call salloc (va, IM_MAXDIM, TY_LONG) + call salloc (vb, IM_MAXDIM, TY_LONG) + + # Determine the image section parameters. This must be in terms of + # the data image pixel coordinates though the section may be specified + # in terms of the reference image coordinates. Limit the number of + # pixels in each dimension to a maximum. + + ndim = IM_NDIM(im) + if (project) + ndim = ndim - 1 + call amovki (1, Memi[v1], IM_MAXDIM) + call amovki (1, Memi[va], IM_MAXDIM) + call amovki (1, Memi[dv], IM_MAXDIM) + call amovi (IM_LEN(imref,1), Memi[vb], ndim) + call ic_section (section, Memi[va], Memi[vb], Memi[dv], ndim) + if (im != imref) + do i = 1, ndim { + Memi[va+i-1] = Memi[va+i-1] - offsets[image,i] + Memi[vb+i-1] = Memi[vb+i-1] - offsets[image,i] + } + + do j = 1, 10 { + n = 1 + do i = 0, ndim-1 { + Memi[v1+i] = max (1, min (Memi[va+i], Memi[vb+i])) + Memi[v2+i] = min (IM_LEN(im,i+1), max (Memi[va+i], Memi[vb+i])) + Memi[dv+i] = j + nv = max (1, (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + Memi[v2+i] = Memi[v1+i] + (nv - 1) * Memi[dv+i] + n = n * nv + } + if (n < NMAX) + break + } + + call amovl (Memi[v1], Memi[va], IM_MAXDIM) + Memi[va] = 1 + if (project) + Memi[va+ndim] = image + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + + # Accumulate the pixel values within the section. Masked pixels and + # thresholded pixels are ignored. + + call salloc (data, n, TY_SHORT) + dp = data + while (imgnls (im, lp, Memi[vb]) != EOF) { + call ic_mget1 (im, image, offsets[image,1], Memi[va], mask) + lp = lp + Memi[v1] - 1 + if (dflag == D_ALL) { + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + a = Mems[lp] + if (a >= lthresh && a <= hthresh) { + Mems[dp] = a + dp = dp + 1 + } + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + Mems[dp] = Mems[lp] + dp = dp + 1 + lp = lp + Memi[dv] + } + } + } else if (dflag == D_MIX) { + mp = mask + Memi[v1] - 1 + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + a = Mems[lp] + if (a >= lthresh && a <= hthresh) { + Mems[dp] = a + dp = dp + 1 + } + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + Mems[dp] = Mems[lp] + dp = dp + 1 + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } + } + for (i=2; i<=ndim; i=i+1) { + Memi[va+i-1] = Memi[va+i-1] + Memi[dv+i-1] + if (Memi[va+i-1] <= Memi[v2+i-1]) + break + Memi[va+i-1] = Memi[v1+i-1] + } + if (i > ndim) + break + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + } + + n = dp - data + if (n < 1) { + call sfree (sp) + call error (1, "Image section contains no pixels") + } + + # Compute only statistics needed. + if (domode || domedian) { + call asrts (Mems[data], Mems[data], n) + mode = ic_modes (Mems[data], n) + median = Mems[data+n/2-1] + } + if (domean) + mean = asums (Mems[data], n) / n + + call sfree (sp) +end + + +define NMIN 10 # Minimum number of pixels for mode calculation +define ZRANGE 0.8 # Fraction of pixels about median to use +define ZSTEP 0.01 # Step size for search for mode +define ZBIN 0.1 # Bin size for mode. + +# IC_MODE -- Compute mode of an array. The mode is found by binning +# with a bin size based on the data range over a fraction of the +# pixels about the median and a bin step which may be smaller than the +# bin size. If there are too few points the median is returned. +# The input array must be sorted. + +short procedure ic_modes (a, n) + +short a[n] # Data array +int n # Number of points + +int i, j, k, nmax +real z1, z2, zstep, zbin +short mode +bool fp_equalr() + +begin + if (n < NMIN) + return (a[n/2]) + + # Compute the mode. The array must be sorted. Consider a + # range of values about the median point. Use a bin size which + # is ZBIN of the range. Step the bin limits in ZSTEP fraction of + # the bin size. + + i = 1 + n * (1. - ZRANGE) / 2. + j = 1 + n * (1. + ZRANGE) / 2. + z1 = a[i] + z2 = a[j] + if (fp_equalr (z1, z2)) { + mode = z1 + return (mode) + } + + zstep = ZSTEP * (z2 - z1) + zbin = ZBIN * (z2 - z1) + zstep = max (1., zstep) + zbin = max (1., zbin) + + z1 = z1 - zstep + k = i + nmax = 0 + repeat { + z1 = z1 + zstep + z2 = z1 + zbin + for (; i < j && a[i] < z1; i=i+1) + ; + for (; k < j && a[k] < z2; k=k+1) + ; + if (k - i > nmax) { + nmax = k - i + mode = a[(i+k)/2] + } + } until (k >= j) + + return (mode) +end + +# IC_STAT -- Compute image statistics within specified section. +# The image section is relative to a reference image which may be +# different than the input image and may have an offset. Only a +# subsample of pixels is used. Masked and thresholded pixels are +# ignored. Only the desired statistics are computed to increase +# efficiency. + +procedure ic_stati (im, imref, section, offsets, image, nimages, + domode, domedian, domean, mode, median, mean) + +pointer im # Data image +pointer imref # Reference image for image section +char section[ARB] # Image section +int offsets[nimages,ARB] # Image section offset from data to reference +int image # Image index (for mask I/O) +int nimages # Number of images in offsets. +bool domode, domedian, domean # Statistics to compute +real mode, median, mean # Statistics + +int i, j, ndim, n, nv +real a +pointer sp, v1, v2, dv, va, vb +pointer data, mask, dp, lp, mp, imgnli() +int ic_modei() +real asumi() + + +include "../icombine.com" + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (dv, IM_MAXDIM, TY_LONG) + call salloc (va, IM_MAXDIM, TY_LONG) + call salloc (vb, IM_MAXDIM, TY_LONG) + + # Determine the image section parameters. This must be in terms of + # the data image pixel coordinates though the section may be specified + # in terms of the reference image coordinates. Limit the number of + # pixels in each dimension to a maximum. + + ndim = IM_NDIM(im) + if (project) + ndim = ndim - 1 + call amovki (1, Memi[v1], IM_MAXDIM) + call amovki (1, Memi[va], IM_MAXDIM) + call amovki (1, Memi[dv], IM_MAXDIM) + call amovi (IM_LEN(imref,1), Memi[vb], ndim) + call ic_section (section, Memi[va], Memi[vb], Memi[dv], ndim) + if (im != imref) + do i = 1, ndim { + Memi[va+i-1] = Memi[va+i-1] - offsets[image,i] + Memi[vb+i-1] = Memi[vb+i-1] - offsets[image,i] + } + + do j = 1, 10 { + n = 1 + do i = 0, ndim-1 { + Memi[v1+i] = max (1, min (Memi[va+i], Memi[vb+i])) + Memi[v2+i] = min (IM_LEN(im,i+1), max (Memi[va+i], Memi[vb+i])) + Memi[dv+i] = j + nv = max (1, (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + Memi[v2+i] = Memi[v1+i] + (nv - 1) * Memi[dv+i] + n = n * nv + } + if (n < NMAX) + break + } + + call amovl (Memi[v1], Memi[va], IM_MAXDIM) + Memi[va] = 1 + if (project) + Memi[va+ndim] = image + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + + # Accumulate the pixel values within the section. Masked pixels and + # thresholded pixels are ignored. + + call salloc (data, n, TY_INT) + dp = data + while (imgnli (im, lp, Memi[vb]) != EOF) { + call ic_mget1 (im, image, offsets[image,1], Memi[va], mask) + lp = lp + Memi[v1] - 1 + if (dflag == D_ALL) { + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + a = Memi[lp] + if (a >= lthresh && a <= hthresh) { + Memi[dp] = a + dp = dp + 1 + } + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + Memi[dp] = Memi[lp] + dp = dp + 1 + lp = lp + Memi[dv] + } + } + } else if (dflag == D_MIX) { + mp = mask + Memi[v1] - 1 + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + a = Memi[lp] + if (a >= lthresh && a <= hthresh) { + Memi[dp] = a + dp = dp + 1 + } + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + Memi[dp] = Memi[lp] + dp = dp + 1 + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } + } + for (i=2; i<=ndim; i=i+1) { + Memi[va+i-1] = Memi[va+i-1] + Memi[dv+i-1] + if (Memi[va+i-1] <= Memi[v2+i-1]) + break + Memi[va+i-1] = Memi[v1+i-1] + } + if (i > ndim) + break + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + } + + n = dp - data + if (n < 1) { + call sfree (sp) + call error (1, "Image section contains no pixels") + } + + # Compute only statistics needed. + if (domode || domedian) { + call asrti (Memi[data], Memi[data], n) + mode = ic_modei (Memi[data], n) + median = Memi[data+n/2-1] + } + if (domean) + mean = asumi (Memi[data], n) / n + + call sfree (sp) +end + + +define NMIN 10 # Minimum number of pixels for mode calculation +define ZRANGE 0.8 # Fraction of pixels about median to use +define ZSTEP 0.01 # Step size for search for mode +define ZBIN 0.1 # Bin size for mode. + +# IC_MODE -- Compute mode of an array. The mode is found by binning +# with a bin size based on the data range over a fraction of the +# pixels about the median and a bin step which may be smaller than the +# bin size. If there are too few points the median is returned. +# The input array must be sorted. + +int procedure ic_modei (a, n) + +int a[n] # Data array +int n # Number of points + +int i, j, k, nmax +real z1, z2, zstep, zbin +int mode +bool fp_equalr() + +begin + if (n < NMIN) + return (a[n/2]) + + # Compute the mode. The array must be sorted. Consider a + # range of values about the median point. Use a bin size which + # is ZBIN of the range. Step the bin limits in ZSTEP fraction of + # the bin size. + + i = 1 + n * (1. - ZRANGE) / 2. + j = 1 + n * (1. + ZRANGE) / 2. + z1 = a[i] + z2 = a[j] + if (fp_equalr (z1, z2)) { + mode = z1 + return (mode) + } + + zstep = ZSTEP * (z2 - z1) + zbin = ZBIN * (z2 - z1) + zstep = max (1., zstep) + zbin = max (1., zbin) + + z1 = z1 - zstep + k = i + nmax = 0 + repeat { + z1 = z1 + zstep + z2 = z1 + zbin + for (; i < j && a[i] < z1; i=i+1) + ; + for (; k < j && a[k] < z2; k=k+1) + ; + if (k - i > nmax) { + nmax = k - i + mode = a[(i+k)/2] + } + } until (k >= j) + + return (mode) +end + +# IC_STAT -- Compute image statistics within specified section. +# The image section is relative to a reference image which may be +# different than the input image and may have an offset. Only a +# subsample of pixels is used. Masked and thresholded pixels are +# ignored. Only the desired statistics are computed to increase +# efficiency. + +procedure ic_statr (im, imref, section, offsets, image, nimages, + domode, domedian, domean, mode, median, mean) + +pointer im # Data image +pointer imref # Reference image for image section +char section[ARB] # Image section +int offsets[nimages,ARB] # Image section offset from data to reference +int image # Image index (for mask I/O) +int nimages # Number of images in offsets. +bool domode, domedian, domean # Statistics to compute +real mode, median, mean # Statistics + +int i, j, ndim, n, nv +real a +pointer sp, v1, v2, dv, va, vb +pointer data, mask, dp, lp, mp, imgnlr() +real ic_moder() +real asumr() + + +include "../icombine.com" + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (dv, IM_MAXDIM, TY_LONG) + call salloc (va, IM_MAXDIM, TY_LONG) + call salloc (vb, IM_MAXDIM, TY_LONG) + + # Determine the image section parameters. This must be in terms of + # the data image pixel coordinates though the section may be specified + # in terms of the reference image coordinates. Limit the number of + # pixels in each dimension to a maximum. + + ndim = IM_NDIM(im) + if (project) + ndim = ndim - 1 + call amovki (1, Memi[v1], IM_MAXDIM) + call amovki (1, Memi[va], IM_MAXDIM) + call amovki (1, Memi[dv], IM_MAXDIM) + call amovi (IM_LEN(imref,1), Memi[vb], ndim) + call ic_section (section, Memi[va], Memi[vb], Memi[dv], ndim) + if (im != imref) + do i = 1, ndim { + Memi[va+i-1] = Memi[va+i-1] - offsets[image,i] + Memi[vb+i-1] = Memi[vb+i-1] - offsets[image,i] + } + + do j = 1, 10 { + n = 1 + do i = 0, ndim-1 { + Memi[v1+i] = max (1, min (Memi[va+i], Memi[vb+i])) + Memi[v2+i] = min (IM_LEN(im,i+1), max (Memi[va+i], Memi[vb+i])) + Memi[dv+i] = j + nv = max (1, (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + Memi[v2+i] = Memi[v1+i] + (nv - 1) * Memi[dv+i] + n = n * nv + } + if (n < NMAX) + break + } + + call amovl (Memi[v1], Memi[va], IM_MAXDIM) + Memi[va] = 1 + if (project) + Memi[va+ndim] = image + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + + # Accumulate the pixel values within the section. Masked pixels and + # thresholded pixels are ignored. + + call salloc (data, n, TY_REAL) + dp = data + while (imgnlr (im, lp, Memi[vb]) != EOF) { + call ic_mget1 (im, image, offsets[image,1], Memi[va], mask) + lp = lp + Memi[v1] - 1 + if (dflag == D_ALL) { + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + a = Memr[lp] + if (a >= lthresh && a <= hthresh) { + Memr[dp] = a + dp = dp + 1 + } + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + Memr[dp] = Memr[lp] + dp = dp + 1 + lp = lp + Memi[dv] + } + } + } else if (dflag == D_MIX) { + mp = mask + Memi[v1] - 1 + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + a = Memr[lp] + if (a >= lthresh && a <= hthresh) { + Memr[dp] = a + dp = dp + 1 + } + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + Memr[dp] = Memr[lp] + dp = dp + 1 + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } + } + for (i=2; i<=ndim; i=i+1) { + Memi[va+i-1] = Memi[va+i-1] + Memi[dv+i-1] + if (Memi[va+i-1] <= Memi[v2+i-1]) + break + Memi[va+i-1] = Memi[v1+i-1] + } + if (i > ndim) + break + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + } + + n = dp - data + if (n < 1) { + call sfree (sp) + call error (1, "Image section contains no pixels") + } + + # Compute only statistics needed. + if (domode || domedian) { + call asrtr (Memr[data], Memr[data], n) + mode = ic_moder (Memr[data], n) + median = Memr[data+n/2-1] + } + if (domean) + mean = asumr (Memr[data], n) / n + + call sfree (sp) +end + + +define NMIN 10 # Minimum number of pixels for mode calculation +define ZRANGE 0.8 # Fraction of pixels about median to use +define ZSTEP 0.01 # Step size for search for mode +define ZBIN 0.1 # Bin size for mode. + +# IC_MODE -- Compute mode of an array. The mode is found by binning +# with a bin size based on the data range over a fraction of the +# pixels about the median and a bin step which may be smaller than the +# bin size. If there are too few points the median is returned. +# The input array must be sorted. + +real procedure ic_moder (a, n) + +real a[n] # Data array +int n # Number of points + +int i, j, k, nmax +real z1, z2, zstep, zbin +real mode +bool fp_equalr() + +begin + if (n < NMIN) + return (a[n/2]) + + # Compute the mode. The array must be sorted. Consider a + # range of values about the median point. Use a bin size which + # is ZBIN of the range. Step the bin limits in ZSTEP fraction of + # the bin size. + + i = 1 + n * (1. - ZRANGE) / 2. + j = 1 + n * (1. + ZRANGE) / 2. + z1 = a[i] + z2 = a[j] + if (fp_equalr (z1, z2)) { + mode = z1 + return (mode) + } + + zstep = ZSTEP * (z2 - z1) + zbin = ZBIN * (z2 - z1) + + z1 = z1 - zstep + k = i + nmax = 0 + repeat { + z1 = z1 + zstep + z2 = z1 + zbin + for (; i < j && a[i] < z1; i=i+1) + ; + for (; k < j && a[k] < z2; k=k+1) + ; + if (k - i > nmax) { + nmax = k - i + mode = a[(i+k)/2] + } + } until (k >= j) + + return (mode) +end + +# IC_STAT -- Compute image statistics within specified section. +# The image section is relative to a reference image which may be +# different than the input image and may have an offset. Only a +# subsample of pixels is used. Masked and thresholded pixels are +# ignored. Only the desired statistics are computed to increase +# efficiency. + +procedure ic_statd (im, imref, section, offsets, image, nimages, + domode, domedian, domean, mode, median, mean) + +pointer im # Data image +pointer imref # Reference image for image section +char section[ARB] # Image section +int offsets[nimages,ARB] # Image section offset from data to reference +int image # Image index (for mask I/O) +int nimages # Number of images in offsets. +bool domode, domedian, domean # Statistics to compute +real mode, median, mean # Statistics + +int i, j, ndim, n, nv +real a +pointer sp, v1, v2, dv, va, vb +pointer data, mask, dp, lp, mp, imgnld() +double ic_moded() +double asumd() + + +include "../icombine.com" + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (dv, IM_MAXDIM, TY_LONG) + call salloc (va, IM_MAXDIM, TY_LONG) + call salloc (vb, IM_MAXDIM, TY_LONG) + + # Determine the image section parameters. This must be in terms of + # the data image pixel coordinates though the section may be specified + # in terms of the reference image coordinates. Limit the number of + # pixels in each dimension to a maximum. + + ndim = IM_NDIM(im) + if (project) + ndim = ndim - 1 + call amovki (1, Memi[v1], IM_MAXDIM) + call amovki (1, Memi[va], IM_MAXDIM) + call amovki (1, Memi[dv], IM_MAXDIM) + call amovi (IM_LEN(imref,1), Memi[vb], ndim) + call ic_section (section, Memi[va], Memi[vb], Memi[dv], ndim) + if (im != imref) + do i = 1, ndim { + Memi[va+i-1] = Memi[va+i-1] - offsets[image,i] + Memi[vb+i-1] = Memi[vb+i-1] - offsets[image,i] + } + + do j = 1, 10 { + n = 1 + do i = 0, ndim-1 { + Memi[v1+i] = max (1, min (Memi[va+i], Memi[vb+i])) + Memi[v2+i] = min (IM_LEN(im,i+1), max (Memi[va+i], Memi[vb+i])) + Memi[dv+i] = j + nv = max (1, (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + Memi[v2+i] = Memi[v1+i] + (nv - 1) * Memi[dv+i] + n = n * nv + } + if (n < NMAX) + break + } + + call amovl (Memi[v1], Memi[va], IM_MAXDIM) + Memi[va] = 1 + if (project) + Memi[va+ndim] = image + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + + # Accumulate the pixel values within the section. Masked pixels and + # thresholded pixels are ignored. + + call salloc (data, n, TY_DOUBLE) + dp = data + while (imgnld (im, lp, Memi[vb]) != EOF) { + call ic_mget1 (im, image, offsets[image,1], Memi[va], mask) + lp = lp + Memi[v1] - 1 + if (dflag == D_ALL) { + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + a = Memd[lp] + if (a >= lthresh && a <= hthresh) { + Memd[dp] = a + dp = dp + 1 + } + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + Memd[dp] = Memd[lp] + dp = dp + 1 + lp = lp + Memi[dv] + } + } + } else if (dflag == D_MIX) { + mp = mask + Memi[v1] - 1 + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + a = Memd[lp] + if (a >= lthresh && a <= hthresh) { + Memd[dp] = a + dp = dp + 1 + } + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + Memd[dp] = Memd[lp] + dp = dp + 1 + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } + } + for (i=2; i<=ndim; i=i+1) { + Memi[va+i-1] = Memi[va+i-1] + Memi[dv+i-1] + if (Memi[va+i-1] <= Memi[v2+i-1]) + break + Memi[va+i-1] = Memi[v1+i-1] + } + if (i > ndim) + break + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + } + + n = dp - data + if (n < 1) { + call sfree (sp) + call error (1, "Image section contains no pixels") + } + + # Compute only statistics needed. + if (domode || domedian) { + call asrtd (Memd[data], Memd[data], n) + mode = ic_moded (Memd[data], n) + median = Memd[data+n/2-1] + } + if (domean) + mean = asumd (Memd[data], n) / n + + call sfree (sp) +end + + +define NMIN 10 # Minimum number of pixels for mode calculation +define ZRANGE 0.8 # Fraction of pixels about median to use +define ZSTEP 0.01 # Step size for search for mode +define ZBIN 0.1 # Bin size for mode. + +# IC_MODE -- Compute mode of an array. The mode is found by binning +# with a bin size based on the data range over a fraction of the +# pixels about the median and a bin step which may be smaller than the +# bin size. If there are too few points the median is returned. +# The input array must be sorted. + +double procedure ic_moded (a, n) + +double a[n] # Data array +int n # Number of points + +int i, j, k, nmax +real z1, z2, zstep, zbin +double mode +bool fp_equalr() + +begin + if (n < NMIN) + return (a[n/2]) + + # Compute the mode. The array must be sorted. Consider a + # range of values about the median point. Use a bin size which + # is ZBIN of the range. Step the bin limits in ZSTEP fraction of + # the bin size. + + i = 1 + n * (1. - ZRANGE) / 2. + j = 1 + n * (1. + ZRANGE) / 2. + z1 = a[i] + z2 = a[j] + if (fp_equalr (z1, z2)) { + mode = z1 + return (mode) + } + + zstep = ZSTEP * (z2 - z1) + zbin = ZBIN * (z2 - z1) + + z1 = z1 - zstep + k = i + nmax = 0 + repeat { + z1 = z1 + zstep + z2 = z1 + zbin + for (; i < j && a[i] < z1; i=i+1) + ; + for (; k < j && a[k] < z2; k=k+1) + ; + if (k - i > nmax) { + nmax = k - i + mode = a[(i+k)/2] + } + } until (k >= j) + + return (mode) +end + diff --git a/pkg/obsolete/imcombine/generic/mkpkg b/pkg/obsolete/imcombine/generic/mkpkg new file mode 100644 index 00000000..8e80222b --- /dev/null +++ b/pkg/obsolete/imcombine/generic/mkpkg @@ -0,0 +1,23 @@ +# Make IMCOMBINE. + +$checkout libpkg.a ../../../../ +$update libpkg.a +$checkin libpkg.a ../../../../ +$exit + +libpkg.a: + icaclip.x ../icombine.com ../icombine.h + icaverage.x ../icombine.com ../icombine.h <imhdr.h> + iccclip.x ../icombine.com ../icombine.h + icgdata.x ../icombine.com ../icombine.h <imhdr.h> <mach.h> + icgrow.x ../icombine.com ../icombine.h <imhdr.h> <pmset.h> + icmedian.x ../icombine.com ../icombine.h + icmm.x ../icombine.com ../icombine.h + icombine.x ../icombine.com ../icombine.h <error.h> <imhdr.h>\ + <imset.h> <mach.h> <pmset.h> <syserr.h> + icpclip.x ../icombine.com ../icombine.h + icsclip.x ../icombine.com ../icombine.h + icsigma.x ../icombine.com ../icombine.h <imhdr.h> + icsort.x + icstat.x ../icombine.com ../icombine.h <imhdr.h> + ; diff --git a/pkg/obsolete/imcombine/icaclip.gx b/pkg/obsolete/imcombine/icaclip.gx new file mode 100644 index 00000000..677e561c --- /dev/null +++ b/pkg/obsolete/imcombine/icaclip.gx @@ -0,0 +1,573 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Minimum number of images for this algorithm + +$for (sird) +# IC_AAVSIGCLIP -- Reject pixels using an average sigma about the average +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_aavsigclip$t (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real average[npts] # Average +$else +PIXEL average[npts] # Average +$endif + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +$if (datatype == sil) +real d1, low, high, sum, a, s, s1, r, one +data one /1.0/ +$else +PIXEL d1, low, high, sum, a, s, s1, r, one +data one /1$f/ +$endif +pointer sp, sums, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (sums, npts, TY_REAL) + call salloc (resid, nimages+1, TY_REAL) + + # Since the unweighted average is computed here possibly skip combining + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Compute the unweighted average with the high and low rejected and + # the poisson scaled average sigma. There must be at least three + # pixels at each point to define the average and contributions to + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + nin = n[1] + s = 0. + n2 = 0 + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) + next + + # Unweighted average with the high and low rejected + low = Mem$t[d[1]+k] + high = Mem$t[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mem$t[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Mem$t[dp1] + l = Memi[mp1] + s1 = max (one, (a + zeros[l]) / scales[l]) + s = s + (d1 - a) ** 2 / s1 + } + } else { + s1 = max (one, a) + do j = 1, n1 + s = s + (Mem$t[d[j]+k] - a) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the average and sum for later. + average[i] = a + Memr[sums+k] = sum + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + + # Reject pixels and compute the final average (if needed). + # There must be at least three pixels at each point for rejection. + # Iteratively scale the mean sigma and reject pixels + # Compact the data and keep track of the image IDs if needed. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (2, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mem$t[d[1]+k] + do j = 2, n1 + sum = sum + Mem$t[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + a = average[i] + sum = Memr[sums+k] + + repeat { + n2 = n1 + if (s > 0.) { + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + d1 = Mem$t[dp1] + l = Memi[mp1] + s1 = s * sqrt (max (one, (a+zeros[l]) / scales[l])) + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + s1 = s * sqrt (max (one, a)) + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Mem$t[dp1] + r = (d1 - a) / s1 + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MAVSIGCLIP -- Reject pixels using an average sigma about the median +# The average sigma is normalized by the expected poisson sigma. + +procedure ic_mavsigclip$t (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real median[npts] # Median +$else +PIXEL median[npts] # Median +$endif + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +pointer sp, resid, mp1, mp2 +$if (datatype == sil) +real med, low, high, r, s, s1, one +data one /1.0/ +$else +PIXEL med, low, high, r, s, s1, one +data one /1$f/ +$endif + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute the poisson scaled average sigma about the median. + # There must be at least three pixels at each point to define + # the mean sigma. Corrections for differences in the image + # scale factors are selected by the doscale1 flag. + + s = 0. + n2 = 0 + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 < 3) { + if (n1 == 0) + median[i] = blank + else if (n1 == 1) + median[i] = Mem$t[d[1]+k] + else { + low = Mem$t[d[1]+k] + high = Mem$t[d[2]+k] + median[i] = (low + high) / 2. + } + next + } + + # Median + n3 = 1 + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mem$t[d[n3-1]+k] + high = Mem$t[d[n3]+k] + med = (low + high) / 2. + } else + med = Mem$t[d[n3]+k] + + # Poisson scaled sigma accumulation + if (doscale1) { + do j = 1, n1 { + l = Memi[m[j]+k] + s1 = max (one, (med + zeros[l]) / scales[l]) + s = s + (Mem$t[d[j]+k] - med) ** 2 / s1 + } + } else { + s1 = max (one, med) + do j = 1, n1 + s = s + (Mem$t[d[j]+k] - med) ** 2 / s1 + } + n2 = n2 + n1 + + # Save the median for later. + median[i] = med + } + + # Here is the final sigma. + if (n2 > 1) + s = sqrt (s / (n2 - 1)) + else + return + + # Compute individual sigmas and iteratively clip. + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 < max (3, maxkeep+1)) + next + nl = 1 + nh = n1 + med = median[i] + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 >= max (MINCLIP, maxkeep+1) && s > 0.) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (med - Mem$t[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s1 = s * sqrt (max (one, (med+zeros[l])/scales[l])) + r = (Mem$t[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + s1 = s * sqrt (max (one, med)) + for (; nl <= n2; nl = nl + 1) { + r = (med - Mem$t[d[nl]+k]) / s1 + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mem$t[d[nh]+k] - med) / s1 + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mem$t[d[n3-1]+k] + high = Mem$t[d[n3]+k] + med = (low + high) / 2. + } else + med = Mem$t[d[n3]+k] + } else + med = blank + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many are rejected add some back in. + # Pixels with equal residuals are added together. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + + # Recompute median + if (n1 < n2) { + if (n1 > 0) { + n3 = nl + n1 / 2 + if (mod (n1, 2) == 0) { + low = Mem$t[d[n3-1]+k] + high = Mem$t[d[n3]+k] + med = (low + high) / 2. + } else + med = Mem$t[d[n3]+k] + } else + med = blank + } + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end +$endfor diff --git a/pkg/obsolete/imcombine/icaverage.gx b/pkg/obsolete/imcombine/icaverage.gx new file mode 100644 index 00000000..505f4577 --- /dev/null +++ b/pkg/obsolete/imcombine/icaverage.gx @@ -0,0 +1,97 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + +$for (sird) +# IC_AVERAGE -- Compute the average image line. +# Options include a weight average. + +procedure ic_average$t (d, m, n, wts, npts, doblank, average) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +int doblank # Set blank values? +$if (datatype == sil) +real average[npts] # Average (returned) +$else +PIXEL average[npts] # Average (returned) +$endif + +int i, j, k +real sumwt, wt +$if (datatype == sil) +real sum +$else +PIXEL sum +$endif + +include "../icombine.com" + +begin + # If no data has been excluded do the average without checking the + # number of points and using the fact that the weights are normalized. + # If all the data has been excluded set the average to the blank value + # if requested. + + if (dflag == D_ALL) { + if (dowts) { + do i = 1, npts { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Mem$t[d[1]+k] * wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Mem$t[d[j]+k] * wt + } + average[i] = sum + } + } else { + do i = 1, npts { + k = i - 1 + sum = Mem$t[d[1]+k] + do j = 2, n[i] + sum = sum + Mem$t[d[j]+k] + average[i] = sum / n[i] + } + } + } else if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + average[i] = blank + } + } else { + if (dowts) { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + wt = wts[Memi[m[1]+k]] + sum = Mem$t[d[1]+k] * wt + sumwt = wt + do j = 2, n[i] { + wt = wts[Memi[m[j]+k]] + sum = sum + Mem$t[d[j]+k] * wt + sumwt = sumwt + wt + } + average[i] = sum / sumwt + } else if (doblank == YES) + average[i] = blank + } + } else { + do i = 1, npts { + if (n[i] > 0) { + k = i - 1 + sum = Mem$t[d[1]+k] + do j = 2, n[i] + sum = sum + Mem$t[d[j]+k] + average[i] = sum / n[i] + } else if (doblank == YES) + average[i] = blank + } + } + } +end +$endfor diff --git a/pkg/obsolete/imcombine/iccclip.gx b/pkg/obsolete/imcombine/iccclip.gx new file mode 100644 index 00000000..609b3448 --- /dev/null +++ b/pkg/obsolete/imcombine/iccclip.gx @@ -0,0 +1,471 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 2 # Mininum number of images for algorithm + +$for (sird) +# IC_ACCDCLIP -- Reject pixels using CCD noise parameters about the average + +procedure ic_accdclip$t (d, m, n, scales, zeros, nm, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model parameters +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real average[npts] # Average +$else +PIXEL average[npts] # Average +$endif + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +$if (datatype == sil) +real d1, low, high, sum, a, s, r, zero +data zero /0.0/ +$else +PIXEL d1, low, high, sum, a, s, r, zero +data zero /0$f/ +$endif +pointer sp, resid, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are no pixels go on to the combining. Since the unweighted + # average is computed here possibly skip the combining later. + + # There must be at least max (1, nkeep) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } else if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # There must be at least two pixels for rejection. The initial + # average is the low/high rejected average except in the case of + # just two pixels. The rejections are iterated and the average + # is recomputed. Corrections for scaling may be performed. + # Depending on other flags the image IDs may also need to be adjusted. + + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 <= max (MINCLIP-1, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mem$t[d[1]+k] + do j = 2, n1 + sum = sum + Mem$t[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + repeat { + if (n1 == 2) { + sum = Mem$t[d[1]+k] + sum = sum + Mem$t[d[2]+k] + a = sum / 2 + } else { + low = Mem$t[d[1]+k] + high = Mem$t[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mem$t[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + } + n2 = n1 + if (doscale1) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + + l = Memi[mp1] + s = scales[l] + d1 = max (zero, s * (a + zeros[l])) + s = sqrt (nm[1,l] + d1/nm[2,l] + (d1*nm[3,l])**2) / s + + d1 = Mem$t[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + mp2 = m[n1] + k + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } else { + if (!keepids) { + s = max (zero, a) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (j=1; j<=n1; j=j+1) { + if (keepids) { + l = Memi[m[j]+k] + s = max (zero, a) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + dp1 = d[j] + k + d1 = Mem$t[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs(r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + } + + n[i] = n1 + if (!docombine) + if (n1 > 0) + average[i] = sum / n1 + else + average[i] = blank + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_CCDCLIP -- Reject pixels using CCD noise parameters about the median + +procedure ic_mccdclip$t (d, m, n, scales, zeros, nm, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +real nm[3,nimages] # Noise model +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real median[npts] # Median +$else +PIXEL median[npts] # Median +$endif + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, mp1, mp2 +$if (datatype == sil) +real med, zero +data zero /0.0/ +$else +PIXEL med, zero +data zero /0$f/ +$endif + +include "../icombine.com" + +begin + # There must be at least max (MINCLIP, nkeep+1) pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) { + med = Mem$t[d[n3-1]+k] + med = (med + Mem$t[d[n3]+k]) / 2. + } else + med = Mem$t[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + for (; nl <= n2; nl = nl + 1) { + l = Memi[m[nl]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (med - Mem$t[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + l = Memi[m[nh]+k] + s = scales[l] + r = max (zero, s * (med + zeros[l])) + s = sqrt (nm[1,l] + r/nm[2,l] + (r*nm[3,l])**2) / s + r = (Mem$t[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } else { + if (!keepids) { + s = max (zero, med) + s = sqrt (nm[1,1] + s/nm[2,1] + (s*nm[3,1])**2) + } + for (; nl <= n2; nl = nl + 1) { + if (keepids) { + l = Memi[m[nl]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (med - Mem$t[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + if (keepids) { + l = Memi[m[nh]+k] + s = max (zero, med) + s = sqrt (nm[1,l] + s/nm[2,l] + (s*nm[3,l])**2) + } + r = (Mem$t[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median is computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end +$endfor diff --git a/pkg/obsolete/imcombine/icgdata.gx b/pkg/obsolete/imcombine/icgdata.gx new file mode 100644 index 00000000..ce71a3eb --- /dev/null +++ b/pkg/obsolete/imcombine/icgdata.gx @@ -0,0 +1,235 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <mach.h> +include "../icombine.h" + +$for (sird) +# IC_GDATA -- Get line of image and mask data and apply threshold and scaling. +# Entirely empty lines are excluded. The data are compacted within the +# input data buffers. If it is required, the connection to the original +# image index is kept in the returned m data pointers. + +procedure ic_gdata$t (in, out, dbuf, d, id, n, m, lflag, offsets, scales, + zeros, nimages, npts, v1, v2) + +pointer in[nimages] # Input images +pointer out[3] # Output images +pointer dbuf[nimages] # Data buffers +pointer d[nimages] # Data pointers +pointer id[nimages] # ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Empty mask flags +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +int nimages # Number of input images +int npts # NUmber of output points per line +long v1[ARB], v2[ARB] # Line vectors + +int i, j, k, l, ndim, nused +real a, b +pointer buf, dp, ip, mp, imgnl$t() + +include "../icombine.com" + +begin + # Get masks and return if there is no data + call ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + if (dflag == D_NONE) { + call aclri (n, npts) + return + } + + # Get data and fill data buffers. Correct for offsets if needed. + ndim = IM_NDIM(out[1]) + do i = 1, nimages { + if (lflag[i] == D_NONE) + next + if (dbuf[i] == NULL) { + call amovl (v1, v2, IM_MAXDIM) + if (project) + v2[ndim+1] = i + j = imgnl$t (in[i], d[i], v2) + } else { + v2[1] = v1[1] + do j = 2, ndim + v2[j] = v1[j] - offsets[i,j] + if (project) + v2[ndim+1] = i + j = imgnl$t (in[i], buf, v2) + call amov$t (Mem$t[buf], Mem$t[dbuf[i]+offsets[i,1]], + IM_LEN(in[i],1)) + d[i] = dbuf[i] + } + } + + # Apply threshold if needed + if (dothresh) { + do i = 1, nimages { + dp = d[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + a = Mem$t[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + lflag[i] = D_MIX + dflag = D_MIX + } + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + a = Mem$t[dp] + if (a < lthresh || a > hthresh) { + Memi[m[i]+j-1] = 1 + dflag = D_MIX + } + } + dp = dp + 1 + mp = mp + 1 + } + } + + # Check for completely empty lines + if (lflag[i] == D_MIX) { + lflag[i] = D_NONE + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + lflag[i] = D_MIX + break + } + mp = mp + 1 + } + } + } + } + + # Apply scaling (avoiding masked pixels which might overflow?) + if (doscale) { + if (dflag == D_ALL) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + do j = 1, npts { + Mem$t[dp] = Mem$t[dp] / a + b + dp = dp + 1 + } + } + } else if (dflag == D_MIX) { + do i = 1, nimages { + dp = d[i] + a = scales[i] + b = -zeros[i] + if (lflag[i] == D_ALL) { + do j = 1, npts { + Mem$t[dp] = Mem$t[dp] / a + b + dp = dp + 1 + } + } else if (lflag[i] == D_MIX) { + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) + Mem$t[dp] = Mem$t[dp] / a + b + dp = dp + 1 + mp = mp + 1 + } + } + } + } + } + + # Sort pointers to exclude unused images. + # Use the lflag array to keep track of the image index. + + if (dflag == D_ALL) + nused = nimages + else { + nused = 0 + do i = 1, nimages + if (lflag[i] != D_NONE) { + nused = nused + 1 + d[nused] = d[i] + m[nused] = m[i] + lflag[nused] = i + } + if (nused == 0) + dflag = D_NONE + } + + # Compact data to remove bad pixels + # Keep track of the image indices if needed + # If growing mark the end of the included image indices with zero + + if (dflag == D_ALL) { + call amovki (nused, n, npts) + if (keepids) + do i = 1, nimages + call amovki (i, Memi[id[i]], npts) + } else if (dflag == D_NONE) + call aclri (n, npts) + else { + call aclri (n, npts) + if (keepids) { + do i = 1, nused { + l = lflag[i] + dp = d[i] + ip = id[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) { + Mem$t[d[k]+j-1] = Mem$t[dp] + Memi[id[k]+j-1] = l + } else + Memi[ip] = l + } + dp = dp + 1 + ip = ip + 1 + mp = mp + 1 + } + } + if (grow >= 1.) { + do j = 1, npts { + do i = n[j]+1, nimages + Memi[id[i]+j-1] = 0 + } + } + } else { + do i = 1, nused { + dp = d[i] + mp = m[i] + do j = 1, npts { + if (Memi[mp] == 0) { + n[j] = n[j] + 1 + k = n[j] + if (k < i) + Mem$t[d[k]+j-1] = Mem$t[dp] + } + dp = dp + 1 + mp = mp + 1 + } + } + } + } + + # Sort the pixels and IDs if needed + if (mclip) { + call malloc (dp, nimages, TY_PIXEL) + if (keepids) { + call malloc (ip, nimages, TY_INT) + call ic_2sort$t (d, Mem$t[dp], id, Memi[ip], n, npts) + call mfree (ip, TY_INT) + } else + call ic_sort$t (d, Mem$t[dp], n, npts) + call mfree (dp, TY_PIXEL) + } +end +$endfor diff --git a/pkg/obsolete/imcombine/icgrow.gx b/pkg/obsolete/imcombine/icgrow.gx new file mode 100644 index 00000000..8b28aec5 --- /dev/null +++ b/pkg/obsolete/imcombine/icgrow.gx @@ -0,0 +1,123 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <pmset.h> +include "../icombine.h" + +# IC_GROW -- Mark neigbors of rejected pixels. +# The rejected pixels (original plus grown) are saved in pixel masks. + +procedure ic_grow (out, v, m, n, buf, nimages, npts, pms) + +pointer out # Output image pointer +long v[ARB] # Output vector +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[npts,nimages] # Working buffer +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k, l, line, nl, rop, igrow, nset, or() +real grow2, i2 +pointer mp, pm, pm_newmask() +errchk pm_newmask() + +include "../icombine.com" + +begin + if (dflag == D_NONE || grow == 0.) + return + + line = v[2] + nl = IM_LEN(out,2) + rop = or (PIX_SRC, PIX_DST) + + igrow = grow + grow2 = grow**2 + do l = 0, igrow { + i2 = grow2 - l * l + call aclri (buf, npts*nimages) + nset = 0 + do j = 1, npts { + do k = n[j]+1, nimages { + mp = Memi[m[k]+j-1] + if (mp == 0) + next + do i = 0, igrow { + if (i**2 > i2) + next + if (j > i) + buf[j-i,mp] = 1 + if (j+i <= npts) + buf[j+i,mp] = 1 + nset = nset + 1 + } + } + } + if (nset == 0) + return + + if (pms == NULL) { + call malloc (pms, nimages, TY_POINTER) + do i = 1, nimages + Memi[pms+i-1] = pm_newmask (out, 1) + } + do i = 1, nimages { + pm = Memi[pms+i-1] + v[2] = line - l + if (v[2] > 0) + call pmplpi (pm, v, buf[1,i], 1, npts, rop) + v[2] = line + l + if (v[2] <= nl) + call pmplpi (pm, v, buf[1,i], 1, npts, rop) + } + } + v[2] = line +end + + +$for (sird) +# IC_GROW$T -- Reject pixels. + +procedure ic_grow$t (v, d, m, n, buf, nimages, npts, pms) + +long v[ARB] # Output vector +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[ARB] # Number of good pixels +int buf[ARB] # Buffer of npts +int nimages # Number of images +int npts # Number of output points per line +pointer pms # Pointer to array of pixel masks + +int i, j, k +pointer pm +bool pl_linenotempty() + +include "../icombine.com" + +begin + do k = 1, nimages { + pm = Memi[pms+k-1] + if (!pl_linenotempty (pm, v)) + next + call pmglpi (pm, v, buf, 1, npts, PIX_SRC) + do i = 1, npts { + if (buf[i] == 0) + next + for (j = 1; j <= n[i]; j = j + 1) { + if (Memi[m[j]+i-1] == k) { + if (j < n[i]) { + Mem$t[d[j]+i-1] = Mem$t[d[n[i]]+i-1] + Memi[m[j]+i-1] = Memi[m[n[i]]+i-1] + } + n[i] = n[i] - 1 + dflag = D_MIX + break + } + } + } + } +end +$endfor diff --git a/pkg/obsolete/imcombine/icimstack.x b/pkg/obsolete/imcombine/icimstack.x new file mode 100644 index 00000000..f3f6eaa5 --- /dev/null +++ b/pkg/obsolete/imcombine/icimstack.x @@ -0,0 +1,129 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> + + +# IC_IMSTACK -- Stack images into a single image of higher dimension. + +procedure ic_imstack (list, output) + +int list #I List of images +char output #I Name of output image + +int i, j, npix +long line_in[IM_MAXDIM], line_out[IM_MAXDIM] +pointer sp, input, key, in, out, buf_in, buf_out, ptr + +int imtgetim(), imtlen() +int imgnls(), imgnli(), imgnll(), imgnlr(), imgnld(), imgnlx() +int impnls(), impnli(), impnll(), impnlr(), impnld(), impnlx() +pointer immap() +errchk immap + +begin + call smark (sp) + call salloc (input, SZ_FNAME, TY_CHAR) + call salloc (key, SZ_FNAME, TY_CHAR) + + iferr { + # Add each input image to the output image. + out = NULL + i = 0 + while (imtgetim (list, Memc[input], SZ_FNAME) != EOF) { + + i = i + 1 + in = NULL + ptr = immap (Memc[input], READ_ONLY, 0) + in = ptr + + # For the first input image map the output image as a copy + # and increment the dimension. Set the output line counter. + + if (i == 1) { + ptr = immap (output, NEW_COPY, in) + out = ptr + IM_NDIM(out) = IM_NDIM(out) + 1 + IM_LEN(out, IM_NDIM(out)) = imtlen (list) + npix = IM_LEN(out, 1) + call amovkl (long(1), line_out, IM_MAXDIM) + } + + # Check next input image for consistency with the output image. + if (IM_NDIM(in) != IM_NDIM(out) - 1) + call error (0, "Input images not consistent") + do j = 1, IM_NDIM(in) { + if (IM_LEN(in, j) != IM_LEN(out, j)) + call error (0, "Input images not consistent") + } + + call sprintf (Memc[key], SZ_FNAME, "stck%04d") + call pargi (i) + call imastr (out, Memc[key], Memc[input]) + + # Copy the input lines from the image to the next lines of + # the output image. Switch on the output data type to optimize + # IMIO. + + call amovkl (long(1), line_in, IM_MAXDIM) + switch (IM_PIXTYPE (out)) { + case TY_SHORT: + while (imgnls (in, buf_in, line_in) != EOF) { + if (impnls (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovs (Mems[buf_in], Mems[buf_out], npix) + } + case TY_INT: + while (imgnli (in, buf_in, line_in) != EOF) { + if (impnli (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovi (Memi[buf_in], Memi[buf_out], npix) + } + case TY_USHORT, TY_LONG: + while (imgnll (in, buf_in, line_in) != EOF) { + if (impnll (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovl (Meml[buf_in], Meml[buf_out], npix) + } + case TY_REAL: + while (imgnlr (in, buf_in, line_in) != EOF) { + if (impnlr (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovr (Memr[buf_in], Memr[buf_out], npix) + } + case TY_DOUBLE: + while (imgnld (in, buf_in, line_in) != EOF) { + if (impnld (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovd (Memd[buf_in], Memd[buf_out], npix) + } + case TY_COMPLEX: + while (imgnlx (in, buf_in, line_in) != EOF) { + if (impnlx (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovx (Memx[buf_in], Memx[buf_out], npix) + } + default: + while (imgnlr (in, buf_in, line_in) != EOF) { + if (impnlr (out, buf_out, line_out) == EOF) + call error (0, "Error writing output image") + call amovr (Memr[buf_in], Memr[buf_out], npix) + } + } + call imunmap (in) + } + } then { + if (out != NULL) { + call imunmap (out) + call imdelete (out) + } + if (in != NULL) + call imunmap (in) + call sfree (sp) + call erract (EA_ERROR) + } + + # Finish up. + call imunmap (out) + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/iclog.x b/pkg/obsolete/imcombine/iclog.x new file mode 100644 index 00000000..f373e9e4 --- /dev/null +++ b/pkg/obsolete/imcombine/iclog.x @@ -0,0 +1,384 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <imset.h> +include <mach.h> +include "icombine.h" + +# IC_LOG -- Output log information is a log file has been specfied. + +procedure ic_log (in, out, ncombine, exptime, sname, zname, wname, + mode, median, mean, scales, zeros, wts, offsets, nimages, + dozero, nout, expname, exposure) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int ncombine[nimages] # Number of previous combined images +real exptime[nimages] # Exposure times +char sname[ARB] # Scale name +char zname[ARB] # Zero name +char wname[ARB] # Weight name +real mode[nimages] # Modes +real median[nimages] # Medians +real mean[nimages] # Means +real scales[nimages] # Scale factors +real zeros[nimages] # Zero or sky levels +real wts[nimages] # Weights +int offsets[nimages,ARB] # Image offsets +int nimages # Number of images +bool dozero # Zero flag +int nout # Number of images combined in output +char expname[ARB] # Exposure name +real exposure # Output exposure + +int i, j, stack, ctor() +real rval, imgetr() +long clktime() +bool prncombine, prexptime, prmode, prmedian, prmean, prmask +bool prrdn, prgain, prsn +pointer sp, fname, key +errchk imgetr + +include "icmask.com" +include "icombine.com" + +begin + if (logfd == NULL) + return + + call smark (sp) + call salloc (fname, SZ_LINE, TY_CHAR) + + stack = NO + if (project) { + ifnoerr (call imgstr (in[1], "stck0001", Memc[fname], SZ_LINE)) + stack = YES + } + if (stack == YES) + call salloc (key, SZ_FNAME, TY_CHAR) + + # Time stamp the log and print parameter information. + + call cnvdate (clktime(0), Memc[fname], SZ_LINE) + call fprintf (logfd, "\n%s: IMCOMBINE\n") + call pargstr (Memc[fname]) + switch (combine) { + case AVERAGE: + call fprintf (logfd, " combine = average, ") + case MEDIAN: + call fprintf (logfd, " combine = median, ") + } + call fprintf (logfd, "scale = %s, zero = %s, weight = %s\n") + call pargstr (sname) + call pargstr (zname) + call pargstr (wname) + + switch (reject) { + case MINMAX: + call fprintf (logfd, " reject = minmax, nlow = %d, nhigh = %d\n") + call pargi (nint (flow * nimages)) + call pargi (nint (fhigh * nimages)) + case CCDCLIP: + call fprintf (logfd, " reject = ccdclip, mclip = %b, nkeep = %d\n") + call pargb (mclip) + call pargi (nkeep) + call fprintf (logfd, + " rdnoise = %s, gain = %s, snoise = %s, sigma = %g, hsigma = %g\n") + call pargstr (Memc[rdnoise]) + call pargstr (Memc[gain]) + call pargstr (Memc[snoise]) + call pargr (lsigma) + call pargr (hsigma) + case CRREJECT: + call fprintf (logfd, + " reject = crreject, mclip = %b, nkeep = %d\n") + call pargb (mclip) + call pargi (nkeep) + call fprintf (logfd, + " rdnoise = %s, gain = %s, snoise = %s, hsigma = %g\n") + call pargstr (Memc[rdnoise]) + call pargstr (Memc[gain]) + call pargstr (Memc[snoise]) + call pargr (hsigma) + case PCLIP: + call fprintf (logfd, " reject = pclip, nkeep = %d\n") + call pargi (nkeep) + call fprintf (logfd, " pclip = %g, lsigma = %g, hsigma = %g\n") + call pargr (pclip) + call pargr (lsigma) + call pargr (hsigma) + case SIGCLIP: + call fprintf (logfd, " reject = sigclip, mclip = %b, nkeep = %d\n") + call pargb (mclip) + call pargi (nkeep) + call fprintf (logfd, " lsigma = %g, hsigma = %g\n") + call pargr (lsigma) + call pargr (hsigma) + case AVSIGCLIP: + call fprintf (logfd, + " reject = avsigclip, mclip = %b, nkeep = %d\n") + call pargb (mclip) + call pargi (nkeep) + call fprintf (logfd, " lsigma = %g, hsigma = %g\n") + call pargr (lsigma) + call pargr (hsigma) + } + if (reject != NONE && grow >= 1.) { + call fprintf (logfd, " grow = %g\n") + call pargr (grow) + } + if (dothresh) { + if (lthresh > -MAX_REAL && hthresh < MAX_REAL) { + call fprintf (logfd, " lthreshold = %g, hthreshold = %g\n") + call pargr (lthresh) + call pargr (hthresh) + } else if (lthresh > -MAX_REAL) { + call fprintf (logfd, " lthreshold = %g\n") + call pargr (lthresh) + } else { + call fprintf (logfd, " hthreshold = %g\n") + call pargr (hthresh) + } + } + call fprintf (logfd, " blank = %g\n") + call pargr (blank) + call clgstr ("statsec", Memc[fname], SZ_LINE) + if (Memc[fname] != EOS) { + call fprintf (logfd, " statsec = %s\n") + call pargstr (Memc[fname]) + } + + if (mtype != M_NONE) { + switch (mtype) { + case M_BOOLEAN, M_GOODVAL: + call fprintf (logfd, " masktype = goodval, maskval = %d\n") + call pargi (mvalue) + case M_BADVAL: + call fprintf (logfd, " masktype = badval, maskval = %d\n") + call pargi (mvalue) + case M_GOODBITS: + call fprintf (logfd, " masktype = goodbits, maskval = %d\n") + call pargi (mvalue) + case M_BADBITS: + call fprintf (logfd, " masktype = badbits, maskval = %d\n") + call pargi (mvalue) + } + } + + # Print information pertaining to individual images as a set of + # columns with the image name being the first column. Determine + # what information is relevant and print the appropriate header. + + prncombine = false + prexptime = false + prmode = false + prmedian = false + prmean = false + prmask = false + prrdn = false + prgain = false + prsn = false + do i = 1, nimages { + if (ncombine[i] != ncombine[1]) + prncombine = true + if (exptime[i] != exptime[1]) + prexptime = true + if (mode[i] != mode[1]) + prmode = true + if (median[i] != median[1]) + prmedian = true + if (mean[i] != mean[1]) + prmean = true + if (mtype != M_NONE && Memi[pms+i-1] != NULL) + prmask = true + if (reject == CCDCLIP || reject == CRREJECT) { + j = 1 + if (ctor (Memc[rdnoise], j, rval) == 0) + prrdn = true + j = 1 + if (ctor (Memc[gain], j, rval) == 0) + prgain = true + j = 1 + if (ctor (Memc[snoise], j, rval) == 0) + prsn = true + } + } + + call fprintf (logfd, " %20s ") + call pargstr ("Images") + if (prncombine) { + call fprintf (logfd, " %6s") + call pargstr ("N") + } + if (prexptime) { + call fprintf (logfd, " %6s") + call pargstr ("Exp") + } + if (prmode) { + call fprintf (logfd, " %7s") + call pargstr ("Mode") + } + if (prmedian) { + call fprintf (logfd, " %7s") + call pargstr ("Median") + } + if (prmean) { + call fprintf (logfd, " %7s") + call pargstr ("Mean") + } + if (prrdn) { + call fprintf (logfd, " %7s") + call pargstr ("Rdnoise") + } + if (prgain) { + call fprintf (logfd, " %6s") + call pargstr ("Gain") + } + if (prsn) { + call fprintf (logfd, " %6s") + call pargstr ("Snoise") + } + if (doscale) { + call fprintf (logfd, " %6s") + call pargstr ("Scale") + } + if (dozero) { + call fprintf (logfd, " %7s") + call pargstr ("Zero") + } + if (dowts) { + call fprintf (logfd, " %6s") + call pargstr ("Weight") + } + if (!aligned) { + call fprintf (logfd, " %9s") + call pargstr ("Offsets") + } + if (prmask) { + call fprintf (logfd, " %s") + call pargstr ("Maskfile") + } + call fprintf (logfd, "\n") + + do i = 1, nimages { + if (stack == YES) { + call sprintf (Memc[key], SZ_FNAME, "stck%04d") + call pargi (i) + ifnoerr (call imgstr (in[i], Memc[key], Memc[fname], SZ_LINE)) { + call fprintf (logfd, " %21s") + call pargstr (Memc[fname]) + } else { + call imstats (in[i], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " %16s[%3d]") + call pargstr (Memc[fname]) + call pargi (i) + } + } else if (project) { + call imstats (in[i], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " %16s[%3d]") + call pargstr (Memc[fname]) + call pargi (i) + } else { + call imstats (in[i], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " %21s") + call pargstr (Memc[fname]) + } + if (prncombine) { + call fprintf (logfd, " %6d") + call pargi (ncombine[i]) + } + if (prexptime) { + call fprintf (logfd, " %6.1f") + call pargr (exptime[i]) + } + if (prmode) { + call fprintf (logfd, " %7.5g") + call pargr (mode[i]) + } + if (prmedian) { + call fprintf (logfd, " %7.5g") + call pargr (median[i]) + } + if (prmean) { + call fprintf (logfd, " %7.5g") + call pargr (mean[i]) + } + if (prrdn) { + rval = imgetr (in[i], Memc[rdnoise]) + call fprintf (logfd, " %7g") + call pargr (rval) + } + if (prgain) { + rval = imgetr (in[i], Memc[gain]) + call fprintf (logfd, " %6g") + call pargr (rval) + } + if (prsn) { + rval = imgetr (in[i], Memc[snoise]) + call fprintf (logfd, " %6g") + call pargr (rval) + } + if (doscale) { + call fprintf (logfd, " %6.3f") + call pargr (1./scales[i]) + } + if (dozero) { + call fprintf (logfd, " %7.5g") + call pargr (-zeros[i]) + } + if (dowts) { + call fprintf (logfd, " %6.3f") + call pargr (wts[i]) + } + if (!aligned) { + if (IM_NDIM(out[1]) == 1) { + call fprintf (logfd, " %9d") + call pargi (offsets[i,1]) + } else { + do j = 1, IM_NDIM(out[1]) { + call fprintf (logfd, " %4d") + call pargi (offsets[i,j]) + } + } + } + if (prmask && Memi[pms+i-1] != NULL) { + call imgstr (in[i], "BPM", Memc[fname], SZ_LINE) + call fprintf (logfd, " %s") + call pargstr (Memc[fname]) + } + call fprintf (logfd, "\n") + } + + # Log information about the output images. + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, "\n Output image = %s, ncombine = %d") + call pargstr (Memc[fname]) + call pargi (nout) + if (expname[1] != EOS) { + call fprintf (logfd, ", %s = %g") + call pargstr (expname) + call pargr (exposure) + } + call fprintf (logfd, "\n") + + if (out[4] != NULL) { + call imstats (out[4], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " Rejection mask = %s\n") + call pargstr (Memc[fname]) + } + + if (out[2] != NULL) { + call imstats (out[2], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " Pixel list image = %s\n") + call pargstr (Memc[fname]) + } + + if (out[3] != NULL) { + call imstats (out[3], IM_IMAGENAME, Memc[fname], SZ_LINE) + call fprintf (logfd, " Sigma image = %s\n") + call pargstr (Memc[fname]) + } + + call flush (logfd) + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/icmask.com b/pkg/obsolete/imcombine/icmask.com new file mode 100644 index 00000000..baba6f6a --- /dev/null +++ b/pkg/obsolete/imcombine/icmask.com @@ -0,0 +1,8 @@ +# IMCMASK -- Common for IMCOMBINE mask interface. + +int mtype # Mask type +int mvalue # Mask value +pointer bufs # Pointer to data line buffers +pointer pms # Pointer to array of PMIO pointers + +common /imcmask/ mtype, mvalue, bufs, pms diff --git a/pkg/obsolete/imcombine/icmask.x b/pkg/obsolete/imcombine/icmask.x new file mode 100644 index 00000000..9aeec395 --- /dev/null +++ b/pkg/obsolete/imcombine/icmask.x @@ -0,0 +1,314 @@ +include <imhdr.h> +include <pmset.h> +include "icombine.h" + +# IC_MASK -- ICOMBINE mask interface +# +# IC_MOPEN -- Open masks +# IC_MCLOSE -- Close the mask interface +# IC_MGET -- Get lines of mask pixels for all the images +# IC_MGET1 -- Get a line of mask pixels for the specified image + + +# IC_MOPEN -- Open masks. +# Parse and interpret the mask selection parameters. + +procedure ic_mopen (in, out, nimages) + +pointer in[nimages] #I Input images +pointer out[3] #I Output images +int nimages #I Number of images + +int i, npix, npms, clgwrd() +real clgetr() +pointer sp, fname, title, pm, pm_open() +bool invert, pm_empty() +errchk calloc, pm_open, pm_loadf + +include "icmask.com" +include "icombine.com" + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (title, SZ_FNAME, TY_CHAR) + + # Determine the mask parameters and allocate memory. + # The mask buffers are initialize to all excluded so that + # output points outside the input data are always excluded + # and don't need to be set on a line-by-line basis. + + mtype = clgwrd ("masktype", Memc[title], SZ_FNAME, MASKTYPES) + mvalue = clgetr ("maskvalue") + npix = IM_LEN(out[1],1) + call calloc (pms, nimages, TY_POINTER) + call calloc (bufs, nimages, TY_POINTER) + do i = 1, nimages { + call malloc (Memi[bufs+i-1], npix, TY_INT) + call amovki (1, Memi[Memi[bufs+i-1]], npix) + } + + # Check for special cases. The BOOLEAN type is used when only + # zero and nonzero are significant; i.e. the actual mask values are + # not important. The invert flag is used to indicate that + # empty masks are all bad rather the all good. + + if (mtype == 0) + mtype = M_NONE + if (mtype == M_BADBITS && mvalue == 0) + mtype = M_NONE + if (mvalue == 0 && (mtype == M_GOODVAL || mtype == M_GOODBITS)) + mtype = M_BOOLEAN + if ((mtype == M_BADVAL && mvalue == 0) || + (mtype == M_GOODVAL && mvalue != 0) || + (mtype == M_GOODBITS && mvalue == 0)) + invert = true + else + invert = false + + # If mask images are to be used, get the mask name from the image + # header and open it saving the descriptor in the pms array. + # Empty masks (all good) are treated as if there was no mask image. + + npms = 0 + do i = 1, nimages { + if (mtype != M_NONE) { + ifnoerr (call imgstr (in[i], "BPM", Memc[fname], SZ_FNAME)) { + pm = pm_open (NULL) + call pm_loadf (pm, Memc[fname], Memc[title], SZ_FNAME) + call pm_seti (pm, P_REFIM, in[i]) + if (pm_empty (pm) && !invert) + call pm_close (pm) + else { + if (project) { + npms = nimages + call amovki (pm, Memi[pms], nimages) + } else { + npms = npms + 1 + Memi[pms+i-1] = pm + } + } + if (project) + break + } + } + } + + # If no mask images are found and the mask parameters imply that + # good values are 0 then use the special case of no masks. + + if (npms == 0) { + if (!invert) + mtype = M_NONE + } + + call sfree (sp) +end + + +# IC_MCLOSE -- Close the mask interface. + +procedure ic_mclose (nimages) + +int nimages # Number of images + +int i +include "icmask.com" +include "icombine.com" + +begin + do i = 1, nimages + call mfree (Memi[bufs+i-1], TY_INT) + do i = 1, nimages { + if (Memi[pms+i-1] != NULL) + call pm_close (Memi[pms+i-1]) + if (project) + break + } + call mfree (pms, TY_POINTER) + call mfree (bufs, TY_POINTER) +end + + +# IC_MGET -- Get lines of mask pixels in the output coordinate system. +# This converts the mask format to an array where zero is good and nonzero +# is bad. This has special cases for optimization. + +procedure ic_mget (in, out, offsets, v1, v2, m, lflag, nimages) + +pointer in[nimages] # Input image pointers +pointer out[3] # Output image pointer +int offsets[nimages,ARB] # Offsets to output image +long v1[IM_MAXDIM] # Data vector desired in output image +long v2[IM_MAXDIM] # Data vector in input image +pointer m[nimages] # Pointer to mask pointers +int lflag[nimages] # Line flags +int nimages # Number of images + +int i, j, ndim, nout, npix +pointer buf, pm +bool pm_linenotempty() +errchk pm_glpi + +include "icmask.com" +include "icombine.com" + +begin + # Determine if masks are needed at all. Note that the threshold + # is applied by simulating mask values so the mask pointers have to + # be set. + + if (mtype == M_NONE && aligned && !dothresh) { + dflag = D_ALL + return + } + + # Set the mask pointers and line flags and apply offsets if needed. + + ndim = IM_NDIM(out[1]) + nout = IM_LEN(out[1],1) + do i = 1, nimages { + npix = IM_LEN(in[i],1) + j = offsets[i,1] + m[i] = Memi[bufs+i-1] + buf = Memi[bufs+i-1] + j + pm = Memi[pms+i-1] + if (npix == nout) + lflag[i] = D_ALL + else + lflag[i] = D_MIX + + v2[1] = v1[1] + do j = 2, ndim { + v2[j] = v1[j] - offsets[i,j] + if (v2[j] < 1 || v2[j] > IM_LEN(in[i],j)) { + lflag[i] = D_NONE + break + } + } + if (project) + v2[ndim+1] = i + + if (lflag[i] == D_NONE) + next + + if (pm == NULL) { + call aclri (Memi[buf], npix) + next + } + + # Do mask I/O and convert to appropriate values in order of + # expected usage. + + if (pm_linenotempty (pm, v2)) { + call pm_glpi (pm, v2, Memi[buf], 32, npix, 0) + + if (mtype == M_BOOLEAN) + ; + else if (mtype == M_BADBITS) + call aandki (Memi[buf], mvalue, Memi[buf], npix) + else if (mtype == M_BADVAL) + call abeqki (Memi[buf], mvalue, Memi[buf], npix) + else if (mtype == M_GOODBITS) { + call aandki (Memi[buf], mvalue, Memi[buf], npix) + call abeqki (Memi[buf], 0, Memi[buf], npix) + } else if (mtype == M_GOODVAL) + call abneki (Memi[buf], mvalue, Memi[buf], npix) + + lflag[i] = D_NONE + do j = 1, npix + if (Memi[buf+j-1] == 0) { + lflag[i] = D_MIX + break + } + } else { + if (mtype == M_BOOLEAN || mtype == M_BADBITS) { + call aclri (Memi[buf], npix) + } else if ((mtype == M_BADVAL && mvalue != 0) || + (mtype == M_GOODVAL && mvalue == 0)) { + call aclri (Memi[buf], npix) + } else { + call amovki (1, Memi[buf], npix) + lflag[i] = D_NONE + } + } + } + + # Set overall data flag + dflag = lflag[1] + do i = 2, nimages { + if (lflag[i] != dflag) { + dflag = D_MIX + break + } + } +end + + +# IC_MGET1 -- Get line of mask pixels from a specified image. +# This is used by the IC_STAT procedure. This procedure converts the +# stored mask format to an array where zero is good and nonzero is bad. +# The data vector and returned mask array are in the input image pixel system. + +procedure ic_mget1 (in, image, offset, v, m) + +pointer in # Input image pointer +int image # Image index +int offset # Column offset +long v[IM_MAXDIM] # Data vector desired +pointer m # Pointer to mask + +int i, npix +pointer buf, pm +bool pm_linenotempty() +errchk pm_glpi + +include "icmask.com" +include "icombine.com" + +begin + dflag = D_ALL + if (mtype == M_NONE) + return + + npix = IM_LEN(in,1) + m = Memi[bufs+image-1] + offset + pm = Memi[pms+image-1] + if (pm == NULL) + return + + # Do mask I/O and convert to appropriate values in order of + # expected usage. + + buf = m + if (pm_linenotempty (pm, v)) { + call pm_glpi (pm, v, Memi[buf], 32, npix, 0) + + if (mtype == M_BOOLEAN) + ; + else if (mtype == M_BADBITS) + call aandki (Memi[buf], mvalue, Memi[buf], npix) + else if (mtype == M_BADVAL) + call abeqki (Memi[buf], mvalue, Memi[buf], npix) + else if (mtype == M_GOODBITS) { + call aandki (Memi[buf], mvalue, Memi[buf], npix) + call abeqki (Memi[buf], 0, Memi[buf], npix) + } else if (mtype == M_GOODVAL) + call abneki (Memi[buf], mvalue, Memi[buf], npix) + + dflag = D_NONE + do i = 1, npix + if (Memi[buf+i-1] == 0) { + dflag = D_MIX + break + } + } else { + if (mtype == M_BOOLEAN || mtype == M_BADBITS) { + ; + } else if ((mtype == M_BADVAL && mvalue != 0) || + (mtype == M_GOODVAL && mvalue == 0)) { + ; + } else + dflag = D_NONE + } +end diff --git a/pkg/obsolete/imcombine/icmedian.gx b/pkg/obsolete/imcombine/icmedian.gx new file mode 100644 index 00000000..b70f4302 --- /dev/null +++ b/pkg/obsolete/imcombine/icmedian.gx @@ -0,0 +1,180 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +$for (sird) +# IC_MEDIAN -- Median of lines + +procedure ic_median$t (d, n, npts, doblank, median) + +pointer d[ARB] # Input data line pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line +int doblank # Set blank values? +$if (datatype == sil) +real median[npts] # Median +$else +PIXEL median[npts] # Median +$endif + +int i, j1, j2, j3, k, n1 +bool even +$if (datatype == silx) +real val1, val2, val3 +$else +PIXEL val1, val2, val3 +$endif + +include "../icombine.com" + +begin + if (dflag == D_NONE) { + if (doblank == YES) { + do i = 1, npts + median[i]= blank + } + return + } + + # Check for previous sorting + if (mclip) { + if (dflag == D_ALL) { + n1 = n[1] + even = (mod (n1, 2) == 0) + j1 = n1 / 2 + 1 + j2 = n1 / 2 + do i = 1, npts { + k = i - 1 + if (even) { + val1 = Mem$t[d[j1]+k] + val2 = Mem$t[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Mem$t[d[j1]+k] + } + } else { + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (n1 > 0) { + j1 = n1 / 2 + 1 + if (mod (n1, 2) == 0) { + j2 = n1 / 2 + val1 = Mem$t[d[j1]+k] + val2 = Mem$t[d[j2]+k] + median[i] = (val1 + val2) / 2. + } else + median[i] = Mem$t[d[j1]+k] + } else if (doblank == YES) + median[i] = blank + } + } + return + } + + # Repeatedly exchange the extreme values until there are three + # or fewer pixels. + + do i = 1, npts { + k = i - 1 + n1 = n[i] + while (n1 > 3) { + j1 = 1 + j2 = 1 + $if (datatype == x) + val1 = abs (Mem$t[d[j1]+k]) + $else + val1 = Mem$t[d[j1]+k] + $endif + val2 = val1 + do j3 = 2, n1 { + $if (datatype == x) + val3 = abs (Mem$t[d[j3]+k]) + $else + val3 = Mem$t[d[j3]+k] + $endif + if (val3 > val1) { + j1 = j3 + val1 = val3 + } else if (val3 < val2) { + j2 = j3 + val2 = val3 + } + } + j3 = n1 - 1 + if (j1 < j3 && j2 < j3) { + Mem$t[d[j1]+k] = val3 + Mem$t[d[j2]+k] = Mem$t[d[j3]+k] + Mem$t[d[j3]+k] = val1 + Mem$t[d[n1]+k] = val2 + } else if (j1 < j3) { + if (j2 == j3) { + Mem$t[d[j1]+k] = val3 + Mem$t[d[n1]+k] = val1 + } else { + Mem$t[d[j1]+k] = Mem$t[d[j3]+k] + Mem$t[d[j3]+k] = val1 + } + } else if (j2 < j3) { + if (j1 == j3) { + Mem$t[d[j2]+k] = val3 + Mem$t[d[n1]+k] = val2 + } else { + Mem$t[d[j2]+k] = Mem$t[d[j3]+k] + Mem$t[d[j3]+k] = val2 + } + } + n1 = n1 - 2 + } + + if (n1 == 3) { + $if (datatype == x) + val1 = abs (Mem$t[d[1]+k]) + val2 = abs (Mem$t[d[2]+k]) + val3 = abs (Mem$t[d[3]+k]) + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = Mem$t[d[2]+k] + else if (val1 < val3) # acb + median[i] = Mem$t[d[3]+k] + else # cab + median[i] = Mem$t[d[1]+k] + } else { + if (val2 > val3) # cba + median[i] = Mem$t[d[2]+k] + else if (val1 > val3) # bca + median[i] = Mem$t[d[3]+k] + else # bac + median[i] = Mem$t[d[1]+k] + } + $else + val1 = Mem$t[d[1]+k] + val2 = Mem$t[d[2]+k] + val3 = Mem$t[d[3]+k] + if (val1 < val2) { + if (val2 < val3) # abc + median[i] = val2 + else if (val1 < val3) # acb + median[i] = val3 + else # cab + median[i] = val1 + } else { + if (val2 > val3) # cba + median[i] = val2 + else if (val1 > val3) # bca + median[i] = val3 + else # bac + median[i] = val1 + } + $endif + } else if (n1 == 2) { + val1 = Mem$t[d[1]+k] + val2 = Mem$t[d[2]+k] + median[i] = (val1 + val2) / 2 + } else if (n1 == 1) + median[i] = Mem$t[d[1]+k] + else if (doblank == YES) + median[i] = blank + } +end +$endfor diff --git a/pkg/obsolete/imcombine/icmm.gx b/pkg/obsolete/imcombine/icmm.gx new file mode 100644 index 00000000..10236b92 --- /dev/null +++ b/pkg/obsolete/imcombine/icmm.gx @@ -0,0 +1,181 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +$for (sird) +# IC_MM -- Reject a specified number of high and low pixels + +procedure ic_mm$t (d, m, n, npts) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of good pixels +int npts # Number of output points per line + +int n1, ncombine, npairs, nlow, nhigh, np +int i, i1, j, jmax, jmin +pointer k, kmax, kmin +PIXEL d1, d2, dmin, dmax + +include "../icombine.com" + +begin + if (dflag == D_NONE) + return + + if (dflag == D_ALL) { + n1 = n[1] + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = n1 - nlow - nhigh + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + do i = 1, npts { + i1 = i - 1 + n1 = n[i] + if (dflag == D_MIX) { + nlow = flow * n1 + 0.001 + nhigh = fhigh * n1 + 0.001 + ncombine = max (ncombine, n1 - nlow - nhigh) + npairs = min (nlow, nhigh) + nlow = nlow - npairs + nhigh = nhigh - npairs + } + + # Reject the npairs low and high points. + do np = 1, npairs { + k = d[1] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + dmax = d1; dmin = d1; jmax = 1; jmin = 1; kmax = k; kmin = k + do j = 2, n1 { + d2 = d1 + k = d[j] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } else if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + j = n1 - 1 + if (keepids) { + if (jmax < j) { + if (jmin != j) { + Mem$t[kmax] = d2 + Memi[m[jmax]+i1] = Memi[m[j]+i1] + } else { + Mem$t[kmax] = d1 + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + } + } + if (jmin < j) { + if (jmax != n1) { + Mem$t[kmin] = d1 + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + } else { + Mem$t[kmin] = d2 + Memi[m[jmin]+i1] = Memi[m[j]+i1] + } + } + } else { + if (jmax < j) { + if (jmin != j) + Mem$t[kmax] = d2 + else + Mem$t[kmax] = d1 + } + if (jmin < j) { + if (jmax != n1) + Mem$t[kmin] = d1 + else + Mem$t[kmin] = d2 + } + } + n1 = n1 - 2 + } + + # Reject the excess low points. + do np = 1, nlow { + k = d[1] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + dmin = d1; jmin = 1; kmin = k + do j = 2, n1 { + k = d[j] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + if (d1 < dmin) { + dmin = d1; jmin = j; kmin = k + } + } + if (keepids) { + if (jmin < n1) { + Mem$t[kmin] = d1 + k = Memi[m[jmin]+i1] + Memi[m[jmin]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmin < n1) + Mem$t[kmin] = d1 + } + n1 = n1 - 1 + } + + # Reject the excess high points. + do np = 1, nhigh { + k = d[1] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + dmax = d1; jmax = 1; kmax = k + do j = 2, n1 { + k = d[j] + i1 + $if (datatype == x) + d1 = abs (Mem$t[k]) + $else + d1 = Mem$t[k] + $endif + if (d1 > dmax) { + dmax = d1; jmax = j; kmax = k + } + } + if (keepids) { + if (jmax < n1) { + Mem$t[kmax] = d1 + k = Memi[m[jmax]+i1] + Memi[m[jmax]+i1] = Memi[m[n1]+i1] + Memi[m[n1]+i1] = k + } + } else { + if (jmax < n1) + Mem$t[kmax] = d1 + } + n1 = n1 - 1 + } + n[i] = n1 + } + + if (dflag == D_ALL && npairs + nlow + nhigh > 0) + dflag = D_MIX +end +$endfor diff --git a/pkg/obsolete/imcombine/icombine.com b/pkg/obsolete/imcombine/icombine.com new file mode 100644 index 00000000..f0d3b467 --- /dev/null +++ b/pkg/obsolete/imcombine/icombine.com @@ -0,0 +1,38 @@ +# ICOMBINE Common + +int combine # Combine algorithm +int reject # Rejection algorithm +bool project # Combine across the highest dimension? +real blank # Blank value +pointer rdnoise # CCD read noise +pointer gain # CCD gain +pointer snoise # CCD sensitivity noise +real lthresh # Low threshold +real hthresh # High threshold +int nkeep # Minimum to keep +real lsigma # Low sigma cutoff +real hsigma # High sigma cutoff +real pclip # Number or fraction of pixels from median +real flow # Fraction of low pixels to reject +real fhigh # Fraction of high pixels to reject +real grow # Grow radius +bool mclip # Use median in sigma clipping? +real sigscale # Sigma scaling tolerance +int logfd # Log file descriptor + +# These flags allow special conditions to be optimized. + +int dflag # Data flag (D_ALL, D_NONE, D_MIX) +bool aligned # Are the images aligned? +bool doscale # Do the images have to be scaled? +bool doscale1 # Do the sigma calculations have to be scaled? +bool dothresh # Check pixels outside specified thresholds? +bool dowts # Does the final average have to be weighted? +bool keepids # Keep track of the image indices? +bool docombine # Call the combine procedure? +bool sort # Sort data? + +common /imccom/ combine, reject, blank, rdnoise, gain, snoise, lsigma, hsigma, + lthresh, hthresh, nkeep, pclip, flow, fhigh, grow, logfd, + dflag, sigscale, project, mclip, aligned, doscale, doscale1, + dothresh, dowts, keepids, docombine, sort diff --git a/pkg/obsolete/imcombine/icombine.gx b/pkg/obsolete/imcombine/icombine.gx new file mode 100644 index 00000000..9cb4cb24 --- /dev/null +++ b/pkg/obsolete/imcombine/icombine.gx @@ -0,0 +1,580 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <imset.h> +include <pmset.h> +include <error.h> +include <syserr.h> +include <mach.h> +include "../icombine.h" + + +# ICOMBINE -- Combine images +# +# The memory and open file descriptor limits are checked and an attempt +# to recover is made either by setting the image pixel files to be +# closed after I/O or by notifying the calling program that memory +# ran out and the IMIO buffer size should be reduced. After the checks +# a procedure for the selected combine option is called. +# Because there may be several failure modes when reaching the file +# limits we first assume an error is due to the file limit, except for +# out of memory, and close some pixel files. If the error then repeats +# on accessing the pixels the error is passed back. + +$for (sird) +procedure icombine$t (in, out, offsets, nimages, bufsize) + +pointer in[nimages] # Input images +pointer out[4] # Output images +int offsets[nimages,ARB] # Input image offsets +int nimages # Number of input images +int bufsize # IMIO buffer size + +char str[1] +int i, j, npts, fd, stropen(), errcode(), imstati() +pointer sp, d, id, n, m, lflag, scales, zeros, wts, dbuf +pointer buf, imgl1$t(), impl1i() +errchk stropen, imgl1$t, impl1i +$if (datatype == sil) +pointer impl1r() +errchk impl1r +$else +pointer impl1$t() +errchk impl1$t +$endif + +include "../icombine.com" + +begin + npts = IM_LEN(out[1],1) + + # Allocate memory. + call smark (sp) + call salloc (dbuf, nimages, TY_POINTER) + call salloc (d, nimages, TY_POINTER) + call salloc (id, nimages, TY_POINTER) + call salloc (n, npts, TY_INT) + call salloc (m, nimages, TY_POINTER) + call salloc (lflag, nimages, TY_INT) + call salloc (scales, nimages, TY_REAL) + call salloc (zeros, nimages, TY_REAL) + call salloc (wts, nimages, TY_REAL) + call amovki (D_ALL, Memi[lflag], nimages) + + # If not aligned or growing create data buffers of output length + # otherwise use the IMIO buffers. + + if (!aligned || grow >= 1.) { + do i = 1, nimages + call salloc (Memi[dbuf+i-1], npts, TY_PIXEL) + } else + call amovki (NULL, Memi[dbuf], nimages) + + if (project) { + call imseti (in[1], IM_NBUFS, nimages) + call imseti (in[1], IM_BUFSIZE, bufsize) + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + } else { + # Reserve FD for string operations. + fd = stropen (str, 1, NEW_FILE) + + # Do I/O to the images. + do i = 1, 3 { + if (out[i] != NULL) + call imseti (out[i], IM_BUFSIZE, bufsize) + } + $if (datatype == sil) + buf = impl1r (out[1]) + call aclrr (Memr[buf], npts) + if (out[3] != NULL) { + buf = impl1r (out[3]) + call aclrr (Memr[buf], npts) + } + $else + buf = impl1$t (out[1]) + call aclr$t (Mem$t[buf], npts) + if (out[3] != NULL) { + buf = impl1$t (out[3]) + call aclr$t (Mem$t[buf], npts) + } + $endif + if (out[2] != NULL) { + buf = impl1i (out[2]) + call aclri (Memi[buf], npts) + } + + do i = 1, nimages { + call imseti (in[i], IM_BUFSIZE, bufsize) + iferr (buf = imgl1$t (in[i])) { + switch (errcode()) { + case SYS_MFULL: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + case SYS_FTOOMANYFILES, SYS_IKIOPIX: + if (imstati (in[i], IM_CLOSEFD) == YES) { + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + do j = i-2, nimages + call imseti (in[j], IM_CLOSEFD, YES) + buf = imgl1$t (in[i]) + default: + call sfree (sp) + call strclose (fd) + call erract (EA_ERROR) + } + } + } + + call strclose (fd) + } + + call ic_combine$t (in, out, Memi[dbuf], Memi[d], Memi[id], Memi[n], + Memi[m], Memi[lflag], offsets, Memr[scales], Memr[zeros], + Memr[wts], nimages, npts) +end + + +# IC_COMBINE -- Combine images. + +procedure ic_combine$t (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, wts, nimages, npts) + +pointer in[nimages] # Input images +pointer out[4] # Output image +pointer dbuf[nimages] # Data buffers for nonaligned images +pointer d[nimages] # Data pointers +pointer id[nimages] # Image index ID pointers +int n[npts] # Number of good pixels +pointer m[nimages] # Mask pointers +int lflag[nimages] # Line flags +int offsets[nimages,ARB] # Input image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero offset factors +real wts[nimages] # Combining weights +int nimages # Number of input images +int npts # Number of points per output line + +int i, ext, ctor(), ic_qsort(), errcode() +real r, imgetr() +pointer sp, fname, imname, v1, v2, v3, work +pointer outdata, buf, nm, pms +pointer immap(), impnli() +$if (datatype == sil) +pointer impnlr(), imgnlr() +$else +pointer impnl$t(), imgnl$t +$endif +errchk immap, ic_scale, imgetr, ic_grow, ic_grow$t, ic_rmasks +extern ic_qsort + +include "../icombine.com" +data ext/0/ + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (imname, SZ_FNAME, TY_CHAR) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (v3, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + + call ic_scale (in, out, offsets, scales, zeros, wts, nimages) + + # Set combine parameters + switch (combine) { + case AVERAGE: + if (dowts) + keepids = true + else + keepids = false + case MEDIAN: + dowts = false + keepids = false + } + docombine = true + + # Set rejection algorithm specific parameters + switch (reject) { + case CCDCLIP, CRREJECT: + call salloc (nm, 3*nimages, TY_REAL) + i = 1 + if (ctor (Memc[rdnoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)] = r + } else { + do i = 1, nimages + Memr[nm+3*(i-1)] = imgetr (in[i], Memc[rdnoise]) + } + i = 1 + if (ctor (Memc[gain], i, r) > 0) { + do i = 1, nimages { + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[gain]) + Memr[nm+3*(i-1)+1] = r + Memr[nm+3*(i-1)] = + max ((Memr[nm+3*(i-1)] / r) ** 2, 1e4 / MAX_REAL) + } + } + i = 1 + if (ctor (Memc[snoise], i, r) > 0) { + do i = 1, nimages + Memr[nm+3*(i-1)+2] = r + } else { + do i = 1, nimages { + r = imgetr (in[i], Memc[snoise]) + Memr[nm+3*(i-1)+2] = r + } + } + if (!keepids) { + if (doscale1) + keepids = true + else { + do i = 2, nimages { + if (Memr[nm+3*(i-1)] != Memr[nm] || + Memr[nm+3*(i-1)+1] != Memr[nm+1] || + Memr[nm+3*(i-1)+2] != Memr[nm+2]) { + keepids = true + break + } + } + } + } + if (reject == CRREJECT) + lsigma = MAX_REAL + case MINMAX: + mclip = false + case PCLIP: + mclip = true + case AVSIGCLIP, SIGCLIP: + if (doscale1) + keepids = true + case NONE: + mclip = false + } + + if (out[4] != NULL) + keepids = true + + if (grow >= 1.) { + keepids = true + call salloc (work, npts * nimages, TY_INT) + } + pms = NULL + + if (keepids) { + do i = 1, nimages + call salloc (id[i], npts, TY_INT) + } + + $if (datatype == sil) + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdata$t (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclip$t (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + else + call ic_accdclip$t (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Memr[outdata]) + case MINMAX: + call ic_mm$t (d, id, n, npts) + case PCLIP: + call ic_pclip$t (d, id, n, nimages, npts, Memr[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclip$t (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + else + call ic_asigclip$t (d, id, n, scales, zeros, nimages, npts, + Memr[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclip$t (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + else + call ic_aavsigclip$t (d, id, n, scales, zeros, nimages, + npts, Memr[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_average$t (d, id, n, wts, npts, YES, + Memr[outdata]) + case MEDIAN: + call ic_median$t (d, n, npts, YES, Memr[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigma$t (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + $else + while (impnl$t (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdata$t (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + switch (reject) { + case CCDCLIP, CRREJECT: + if (mclip) + call ic_mccdclip$t (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Mem$t[outdata]) + else + call ic_accdclip$t (d, id, n, scales, zeros, Memr[nm], + nimages, npts, Mem$t[outdata]) + case MINMAX: + call ic_mm$t (d, id, n, npts) + case PCLIP: + call ic_pclip$t (d, id, n, nimages, npts, Mem$t[outdata]) + case SIGCLIP: + if (mclip) + call ic_msigclip$t (d, id, n, scales, zeros, nimages, npts, + Mem$t[outdata]) + else + call ic_asigclip$t (d, id, n, scales, zeros, nimages, npts, + Mem$t[outdata]) + case AVSIGCLIP: + if (mclip) + call ic_mavsigclip$t (d, id, n, scales, zeros, nimages, + npts, Mem$t[outdata]) + else + call ic_aavsigclip$t (d, id, n, scales, zeros, nimages, + npts, Mem$t[outdata]) + } + + if (pms == NULL || nkeep > 0) { + if (docombine) { + switch (combine) { + case AVERAGE: + call ic_average$t (d, id, n, wts, npts, YES, + Mem$t[outdata]) + case MEDIAN: + call ic_median$t (d, n, npts, YES, Mem$t[outdata]) + } + } + } + + if (grow >= 1.) + call ic_grow (out, Meml[v2], id, n, Memi[work], nimages, npts, + pms) + + if (pms == NULL) { + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnl$t (out[3], buf, Meml[v1]) + call ic_sigma$t (d, id, n, wts, npts, Mem$t[outdata], + Mem$t[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + } + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + $endif + + if (pms != NULL) { + if (nkeep > 0) { + call imstats (out[1], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call imunmap (out[1]) + iferr (buf = immap (Memc[fname], READ_WRITE, 0)) { + switch (errcode()) { + case SYS_FXFOPNOEXTNV: + call imgcluster (Memc[fname], Memc[fname], SZ_FNAME) + ext = ext + 1 + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext) + iferr (buf = immap (Memc[imname], READ_WRITE, 0)) { + buf = NULL + ext = 0 + } + repeat { + call sprintf (Memc[imname], SZ_FNAME, "%s[%d]") + call pargstr (Memc[fname]) + call pargi (ext+1) + iferr (outdata = immap (Memc[imname],READ_WRITE,0)) + break + if (buf != NULL) + call imunmap (buf) + buf = outdata + ext = ext + 1 + } + default: + call erract (EA_ERROR) + } + } + out[1] = buf + } + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + call amovkl (long(1), Meml[v3], IM_MAXDIM) + $if (datatype == sil) + while (impnlr (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdata$t (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_grow$t (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnlr (out[1], buf, Meml[v1]) == EOF) + ; + call amovr (Memr[buf], Memr[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_average$t (d, id, n, wts, npts, NO, Memr[outdata]) + case MEDIAN: + call ic_median$t (d, n, npts, NO, Memr[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnlr (out[3], buf, Meml[v1]) + call ic_sigma$t (d, id, n, wts, npts, Memr[outdata], + Memr[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + $else + while (impnl$t (out[1], outdata, Meml[v1]) != EOF) { + call ic_gdata$t (in, out, dbuf, d, id, n, m, lflag, offsets, + scales, zeros, nimages, npts, Meml[v2], Meml[v3]) + + call ic_grow$t (Meml[v2], d, id, n, Memi[work], nimages, npts, + pms) + + if (nkeep > 0) { + do i = 1, npts { + if (n[i] < nkeep) { + Meml[v1+1] = Meml[v1+1] - 1 + if (imgnl$t (out[1], buf, Meml[v1]) == EOF) + ; + call amov$t (Mem$t[buf], Mem$t[outdata], npts) + break + } + } + } + + switch (combine) { + case AVERAGE: + call ic_average$t (d, id, n, wts, npts, NO, Mem$t[outdata]) + case MEDIAN: + call ic_median$t (d, n, npts, NO, Mem$t[outdata]) + } + + if (out[2] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnli (out[2], buf, Meml[v1]) + call amovki (nimages, Memi[buf], npts) + call asubi (Memi[buf], n, Memi[buf], npts) + } + + if (out[3] != NULL) { + call amovl (Meml[v2], Meml[v1], IM_MAXDIM) + i = impnl$t (out[3], buf, Meml[v1]) + call ic_sigma$t (d, id, n, wts, npts, Mem$t[outdata], + Mem$t[buf]) + } + + if (out[4] != NULL) + call ic_rmasks (out[4], Meml[v2], id, nimages, n, npts) + + call amovl (Meml[v1], Meml[v2], IM_MAXDIM) + } + $endif + + do i = 1, nimages + call pm_close (Memi[pms+i-1]) + call mfree (pms, TY_POINTER) + } + + call sfree (sp) +end +$endfor + + +# IC_QSORT -- Compare line numbers for GQSORT. + +int procedure ic_qsort (arg, i1, i2) + +pointer arg +int i1, i2 + +begin + if (Mems[arg+i1-1] < Mems[arg+i2-1]) + return (-1) + else if (Mems[arg+i1-1] > Mems[arg+i2-1]) + return (1) + else + return (0) +end diff --git a/pkg/obsolete/imcombine/icombine.h b/pkg/obsolete/imcombine/icombine.h new file mode 100644 index 00000000..13b77117 --- /dev/null +++ b/pkg/obsolete/imcombine/icombine.h @@ -0,0 +1,52 @@ +# ICOMBINE Definitions + +# Memory management parameters; +define DEFBUFSIZE 65536 # default IMIO buffer size +define FUDGE 0.8 # fudge factor + +# Rejection options: +define REJECT "|none|ccdclip|crreject|minmax|pclip|sigclip|avsigclip|" +define NONE 1 # No rejection algorithm +define CCDCLIP 2 # CCD noise function clipping +define CRREJECT 3 # CCD noise function clipping +define MINMAX 4 # Minmax rejection +define PCLIP 5 # Percentile clip +define SIGCLIP 6 # Sigma clip +define AVSIGCLIP 7 # Sigma clip with average poisson sigma + +# Combine options: +define COMBINE "|average|median|" +define AVERAGE 1 +define MEDIAN 2 + +# Scaling options: +define STYPES "|none|mode|median|mean|exposure|" +define ZTYPES "|none|mode|median|mean|" +define WTYPES "|none|mode|median|mean|exposure|" +define S_NONE 1 +define S_MODE 2 +define S_MEDIAN 3 +define S_MEAN 4 +define S_EXPOSURE 5 +define S_FILE 6 +define S_KEYWORD 7 +define S_SECTION "|input|output|overlap|" +define S_INPUT 1 +define S_OUTPUT 2 +define S_OVERLAP 3 + +# Mask options +define MASKTYPES "|none|goodvalue|badvalue|goodbits|badbits|" +define M_NONE 1 # Don't use mask images +define M_GOODVAL 2 # Value selecting good pixels +define M_BADVAL 3 # Value selecting bad pixels +define M_GOODBITS 4 # Bits selecting good pixels +define M_BADBITS 5 # Bits selecting bad pixels +define M_BOOLEAN -1 # Ignore mask values + +# Data flag +define D_ALL 0 # All pixels are good +define D_NONE 1 # All pixels are bad or rejected +define D_MIX 2 # Mixture of good and bad pixels + +define TOL 0.001 # Tolerance for equal residuals diff --git a/pkg/obsolete/imcombine/icpclip.gx b/pkg/obsolete/imcombine/icpclip.gx new file mode 100644 index 00000000..f0c76369 --- /dev/null +++ b/pkg/obsolete/imcombine/icpclip.gx @@ -0,0 +1,233 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Minimum number for clipping + +$for (sird) +# IC_PCLIP -- Percentile clip +# +# 1) Find the median +# 2) Find the pixel which is the specified order index away +# 3) Use the data value difference as a sigma and apply clipping +# 4) Since the median is known return it so it does not have to be recomputed + +procedure ic_pclip$t (d, m, n, nimages, npts, median) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image id pointers +int n[npts] # Number of good pixels +int nimages # Number of input images +int npts # Number of output points per line +$if (datatype == sil) +real median[npts] # Median +$else +PIXEL median[npts] # Median +$endif + +int i, j, k, l, id, n1, n2, n3, n4, n5, nl, nh, nin, maxkeep +bool even, fp_equalr() +real sigma, r, s, t +pointer sp, resid, mp1, mp2 +$if (datatype == sil) +real med +$else +PIXEL med +$endif + +include "../icombine.com" + +begin + # There must be at least MINCLIP and more than nkeep pixels. + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + + # Set sign of pclip parameter + if (pclip < 0) + t = -1. + else + t = 1. + + # If there are no rejected pixels compute certain parameters once. + if (dflag == D_ALL) { + n1 = n[1] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0.) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + nin = n1 + } + + # Now apply clipping. + do i = 1, npts { + # Compute median. + if (dflag == D_MIX) { + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + if (n1 == 0) { + if (combine == MEDIAN) + median[i] = blank + next + } + n2 = 1 + n1 / 2 + even = (mod (n1, 2) == 0) + if (pclip < 0) { + if (even) + n3 = max (1, nint (n2 - 1 + pclip)) + else + n3 = max (1, nint (n2 + pclip)) + } else + n3 = min (n1, nint (n2 + pclip)) + } + + j = i - 1 + if (even) { + med = Mem$t[d[n2-1]+j] + med = (med + Mem$t[d[n2]+j]) / 2. + } else + med = Mem$t[d[n2]+j] + + if (n1 < max (MINCLIP, maxkeep+1)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Define sigma for clipping + sigma = t * (Mem$t[d[n3]+j] - med) + if (fp_equalr (sigma, 0.)) { + if (combine == MEDIAN) + median[i] = med + next + } + + # Reject pixels and save residuals. + # Check if any pixels are clipped. + # If so recompute the median and reset the number of good pixels. + # Only reorder if needed. + + for (nl=1; nl<=n1; nl=nl+1) { + r = (med - Mem$t[d[nl]+j]) / sigma + if (r < lsigma) + break + Memr[resid+nl] = r + } + for (nh=n1; nh>=1; nh=nh-1) { + r = (Mem$t[d[nh]+j] - med) / sigma + if (r < hsigma) + break + Memr[resid+nh] = r + } + n4 = nh - nl + 1 + + # If too many pixels are rejected add some back in. + # All pixels with the same residual are added. + while (n4 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n4 = nh - nl + 1 + } + + # If any pixels are rejected recompute the median. + if (nl > 1 || nh < n1) { + n5 = nl + n4 / 2 + if (mod (n4, 2) == 0) { + med = Mem$t[d[n5-1]+j] + med = (med + Mem$t[d[n5]+j]) / 2. + } else + med = Mem$t[d[n5]+j] + n[i] = n4 + } + if (combine == MEDIAN) + median[i] = med + + # Reorder if pixels only if necessary. + if (nl > 1 && (combine != MEDIAN || grow >= 1.)) { + k = max (nl, n4 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mem$t[d[l]+j] = Mem$t[d[k]+j] + if (grow >= 1.) { + mp1 = m[l] + j + mp2 = m[k] + j + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+j] = Memi[m[k]+j] + k = k + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mem$t[d[l]+j] = Mem$t[d[k]+j] + k = k + 1 + } + } + } + } + + # Check if data flag needs to be reset for rejected pixels. + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag whether the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end +$endfor diff --git a/pkg/obsolete/imcombine/icrmasks.x b/pkg/obsolete/imcombine/icrmasks.x new file mode 100644 index 00000000..8b9a0c3d --- /dev/null +++ b/pkg/obsolete/imcombine/icrmasks.x @@ -0,0 +1,41 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> + + +# IC_RMASKS -- Set pixels for rejection mask. + +procedure ic_rmasks (pm, v, id, nimages, n, npts) + +pointer pm #I Pixel mask +long v[ARB] #I Output vector (input) +pointer id[nimages] #I Image id pointers +int nimages #I Number of images +int n[npts] #I Number of good pixels +int npts #I Number of output points per line + +int i, j, k, ndim, impnls() +long v1[IM_MAXDIM] +pointer buf + +begin + ndim = IM_NDIM(pm) + do k = 1, nimages { + call amovl (v, v1, ndim-1) + v1[ndim] = k + i = impnls (pm, buf, v1) + do j = 1, npts { + if (n[j] == nimages) + Mems[buf+j-1] = 0 + else { + Mems[buf+j-1] = 1 + do i = 1, n[j] { + if (Memi[id[i]+j-1] == k) { + Mems[buf+j-1] = 0 + break + } + } + } + } + } +end diff --git a/pkg/obsolete/imcombine/icscale.x b/pkg/obsolete/imcombine/icscale.x new file mode 100644 index 00000000..5f4194e6 --- /dev/null +++ b/pkg/obsolete/imcombine/icscale.x @@ -0,0 +1,358 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <imset.h> +include <error.h> +include "icombine.h" + +# IC_SCALE -- Get the scale factors for the images. +# 1. This procedure does CLIO to determine the type of scaling desired. +# 2. The output header parameters for exposure time and NCOMBINE are set. + +procedure ic_scale (in, out, offsets, scales, zeros, wts, nimages) + +pointer in[nimages] # Input images +pointer out[3] # Output images +int offsets[nimages,ARB] # Image offsets +real scales[nimages] # Scale factors +real zeros[nimages] # Zero or sky levels +real wts[nimages] # Weights +int nimages # Number of images + +int stype, ztype, wtype +int i, j, k, l, nout +real mode, median, mean, exposure, zmean +pointer sp, ncombine, exptime, modes, medians, means, expname +pointer section, str, sname, zname, wname, imref +bool domode, domedian, domean, dozero, snorm, znorm, wflag + +int imgeti(), strdic(), ic_gscale() +real imgetr(), asumr(), asumi() +errchk ic_gscale, ic_statr + +include "icombine.com" + +begin + call smark (sp) + call salloc (ncombine, nimages, TY_INT) + call salloc (exptime, nimages, TY_REAL) + call salloc (modes, nimages, TY_REAL) + call salloc (medians, nimages, TY_REAL) + call salloc (means, nimages, TY_REAL) + call salloc (expname, SZ_FNAME, TY_CHAR) + call salloc (section, SZ_FNAME, TY_CHAR) + call salloc (str, SZ_LINE, TY_CHAR) + call salloc (sname, SZ_FNAME, TY_CHAR) + call salloc (zname, SZ_FNAME, TY_CHAR) + call salloc (wname, SZ_FNAME, TY_CHAR) + + # Set the defaults. + call amovki (1, Memi[ncombine], nimages) + call amovkr (0., Memr[exptime], nimages) + call amovkr (INDEF, Memr[modes], nimages) + call amovkr (INDEF, Memr[medians], nimages) + call amovkr (INDEF, Memr[means], nimages) + call amovkr (1., scales, nimages) + call amovkr (0., zeros, nimages) + call amovkr (1., wts, nimages) + + # Get the number of images previously combined and the exposure times. + # The default combine number is 1 and the default exposure is 0. + + call clgstr ("expname", Memc[expname], SZ_FNAME) + do i = 1, nimages { + iferr (Memi[ncombine+i-1] = imgeti (in[i], "ncombine")) + Memi[ncombine+i-1] = 1 + if (Memc[expname] != EOS) { + iferr (Memr[exptime+i-1] = imgetr (in[i], Memc[expname])) + Memr[exptime+i-1] = 0. + } + if (project) { + call amovki (Memi[ncombine], Memi[ncombine], nimages) + call amovkr (Memr[exptime], Memr[exptime], nimages) + break + } + } + + # Set scaling factors. + + stype = ic_gscale ("scale", Memc[sname], STYPES, in, Memr[exptime], + scales, nimages) + ztype = ic_gscale ("zero", Memc[zname], ZTYPES, in, Memr[exptime], + zeros, nimages) + wtype = ic_gscale ("weight", Memc[wname], WTYPES, in, Memr[exptime], + wts, nimages) + + # Get image statistics only if needed. + domode = ((stype==S_MODE)||(ztype==S_MODE)||(wtype==S_MODE)) + domedian = ((stype==S_MEDIAN)||(ztype==S_MEDIAN)||(wtype==S_MEDIAN)) + domean = ((stype==S_MEAN)||(ztype==S_MEAN)||(wtype==S_MEAN)) + if (domode || domedian || domean) { + Memc[section] = EOS + Memc[str] = EOS + call clgstr ("statsec", Memc[section], SZ_FNAME) + call sscan (Memc[section]) + call gargwrd (Memc[section], SZ_FNAME) + call gargwrd (Memc[str], SZ_LINE) + + i = strdic (Memc[section], Memc[section], SZ_FNAME, S_SECTION) + switch (i) { + case S_INPUT: + call strcpy (Memc[str], Memc[section], SZ_FNAME) + imref = NULL + case S_OUTPUT: + call strcpy (Memc[str], Memc[section], SZ_FNAME) + imref = out[1] + case S_OVERLAP: + call strcpy ("[", Memc[section], SZ_FNAME) + do i = 1, IM_NDIM(out[1]) { + k = offsets[1,i] + 1 + l = offsets[1,i] + IM_LEN(in[1],i) + do j = 2, nimages { + k = max (k, offsets[j,i]+1) + l = min (l, offsets[j,i]+IM_LEN(in[j],i)) + } + if (i < IM_NDIM(out[1])) + call sprintf (Memc[str], SZ_LINE, "%d:%d,") + else + call sprintf (Memc[str], SZ_LINE, "%d:%d]") + call pargi (k) + call pargi (l) + call strcat (Memc[str], Memc[section], SZ_FNAME) + } + imref = out[1] + default: + imref = NULL + } + + do i = 1, nimages { + if (imref != out[1]) + imref = in[i] + call ic_statr (in[i], imref, Memc[section], offsets, + i, nimages, domode, domedian, domean, mode, median, mean) + if (domode) { + Memr[modes+i-1] = mode + if (stype == S_MODE) + scales[i] = mode + if (ztype == S_MODE) + zeros[i] = mode + if (wtype == S_MODE) + wts[i] = mode + } + if (domedian) { + Memr[medians+i-1] = median + if (stype == S_MEDIAN) + scales[i] = median + if (ztype == S_MEDIAN) + zeros[i] = median + if (wtype == S_MEDIAN) + wts[i] = median + } + if (domean) { + Memr[means+i-1] = mean + if (stype == S_MEAN) + scales[i] = mean + if (ztype == S_MEAN) + zeros[i] = mean + if (wtype == S_MEAN) + wts[i] = mean + } + } + } + + do i = 1, nimages + if (scales[i] <= 0.) { + call eprintf ("WARNING: Negative scale factors") + call eprintf (" -- ignoring scaling\n") + call amovkr (1., scales, nimages) + break + } + + # Convert to relative factors if needed. + snorm = (stype == S_FILE || stype == S_KEYWORD) + znorm = (ztype == S_FILE || ztype == S_KEYWORD) + wflag = (wtype == S_FILE || wtype == S_KEYWORD) + if (snorm) + call arcpr (1., scales, scales, nimages) + else { + mean = asumr (scales, nimages) / nimages + call adivkr (scales, mean, scales, nimages) + } + call adivr (zeros, scales, zeros, nimages) + zmean = asumr (zeros, nimages) / nimages + + if (wtype != S_NONE) { + do i = 1, nimages { + if (wts[i] <= 0.) { + call eprintf ("WARNING: Negative weights") + call eprintf (" -- using only NCOMBINE weights\n") + do j = 1, nimages + wts[j] = Memi[ncombine+j-1] + break + } + if (ztype == S_NONE || znorm || wflag) + wts[i] = Memi[ncombine+i-1] * wts[i] + else { + if (zeros[i] <= 0.) { + call eprintf ("WARNING: Negative zero offsets") + call eprintf (" -- ignoring zero weight adjustments\n") + do j = 1, nimages + wts[j] = Memi[ncombine+j-1] * wts[j] + break + } + wts[i] = Memi[ncombine+i-1] * wts[i] * zmean / zeros[i] + } + } + } + + if (znorm) + call anegr (zeros, zeros, nimages) + else { + # Because of finite arithmetic it is possible for the zero offsets + # to be nonzero even when they are all equal. Just for the sake of + # a nice log set the zero offsets in this case. + + call asubkr (zeros, zmean, zeros, nimages) + for (i=2; (i<=nimages)&&(zeros[i]==zeros[1]); i=i+1) + ; + if (i > nimages) + call aclrr (zeros, nimages) + } + mean = asumr (wts, nimages) + call adivkr (wts, mean, wts, nimages) + + # Set flags for scaling, zero offsets, sigma scaling, weights. + # Sigma scaling may be suppressed if the scales or zeros are + # different by a specified tolerance. + + doscale = false + dozero = false + doscale1 = false + dowts = false + do i = 2, nimages { + if (snorm || scales[i] != scales[1]) + doscale = true + if (znorm || zeros[i] != zeros[1]) + dozero = true + if (wts[i] != wts[1]) + dowts = true + } + if (doscale && sigscale != 0.) { + do i = 1, nimages { + if (abs (scales[i] - 1) > sigscale) { + doscale1 = true + break + } + } + if (!doscale1 && zmean > 0) { + do i = 1, nimages { + if (abs (zeros[i] / zmean) > sigscale) { + doscale1 = true + break + } + } + } + } + + # Set the output header parameters. + nout = asumi (Memi[ncombine], nimages) + call imaddi (out[1], "ncombine", nout) + if (Memc[expname] != EOS) { + exposure = 0. + do i = 1, nimages + exposure = exposure + wts[i] * Memr[exptime+i-1] / scales[i] + call imaddr (out[1], Memc[expname], exposure) + } else + exposure = INDEF + if (out[2] != NULL) { + call imstats (out[2], IM_IMAGENAME, Memc[str], SZ_FNAME) + call imastr (out[1], "BPM", Memc[str]) + } + ifnoerr (mode = imgetr (out[1], "CCDMEAN")) + call imdelf (out[1], "CCDMEAN") + + # Start the log here since much of the info is only available here. + call ic_log (in, out, Memi[ncombine], Memr[exptime], Memc[sname], + Memc[zname], Memc[wname], Memr[modes], Memr[medians], Memr[means], + scales, zeros, wts, offsets, nimages, dozero, nout, + Memc[expname], exposure) + + doscale = (doscale || dozero) + + call sfree (sp) +end + + +# IC_GSCALE -- Get scale values as directed by CL parameter +# The values can be one of those in the dictionary, from a file specified +# with a @ prefix, or from an image header keyword specified by a ! prefix. + +int procedure ic_gscale (param, name, dic, in, exptime, values, nimages) + +char param[ARB] #I CL parameter name +char name[SZ_FNAME] #O Parameter value +char dic[ARB] #I Dictionary string +pointer in[nimages] #I IMIO pointers +real exptime[nimages] #I Exposure times +real values[nimages] #O Values +int nimages #I Number of images + +int type #O Type of value + +int fd, i, nowhite(), open(), fscan(), nscan(), strdic() +real rval, imgetr() +pointer errstr +errchk open, imgetr() + +include "icombine.com" + +begin + call clgstr (param, name, SZ_FNAME) + if (nowhite (name, name, SZ_FNAME) == 0) + type = S_NONE + else if (name[1] == '@') { + type = S_FILE + fd = open (name[2], READ_ONLY, TEXT_FILE) + i = 0 + while (fscan (fd) != EOF) { + call gargr (rval) + if (nscan() != 1) + next + if (i == nimages) { + call eprintf ( + "Warning: Ignoring additional %s values in %s\n") + call pargstr (param) + call pargstr (name[2]) + break + } + i = i + 1 + values[i] = rval + } + call close (fd) + if (i < nimages) { + call salloc (errstr, SZ_LINE, TY_CHAR) + call sprintf (errstr, SZ_FNAME, "Insufficient %s values in %s") + call pargstr (param) + call pargstr (name[2]) + call error (1, errstr) + } + } else if (name[1] == '!') { + type = S_KEYWORD + do i = 1, nimages { + values[i] = imgetr (in[i], name[2]) + if (project) { + call amovkr (values, values, nimages) + break + } + } + } else { + type = strdic (name, name, SZ_FNAME, dic) + if (type == 0) + call error (1, "Unknown scale, zero, or weight type") + if (type==S_EXPOSURE) + do i = 1, nimages + values[i] = max (0.001, exptime[i]) + } + + return (type) +end diff --git a/pkg/obsolete/imcombine/icsclip.gx b/pkg/obsolete/imcombine/icsclip.gx new file mode 100644 index 00000000..1b1c5de9 --- /dev/null +++ b/pkg/obsolete/imcombine/icsclip.gx @@ -0,0 +1,504 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../icombine.h" + +define MINCLIP 3 # Mininum number of images for algorithm + +$for (sird) +# IC_ASIGCLIP -- Reject pixels using sigma clipping about the average +# The initial average rejects the high and low pixels. A correction for +# different scalings of the images may be made. Weights are not used. + +procedure ic_asigclip$t (d, m, n, scales, zeros, nimages, npts, average) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real average[npts] # Average +$else +PIXEL average[npts] # Average +$endif + +int i, j, k, l, jj, n1, n2, nin, nk, maxkeep +$if (datatype == sil) +real d1, low, high, sum, a, s, r, one +data one /1.0/ +$else +PIXEL d1, low, high, sum, a, s, r, one +data one /1$f/ +$endif +pointer sp, resid, w, wp, dp1, dp2, mp1, mp2 + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Flag whether returned average needs to be recomputed. + if (dowts || combine != AVERAGE) + docombine = true + else + docombine = false + + # Save the residuals and the sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Do sigma clipping. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + + # If there are not enough pixels simply compute the average. + if (n1 < max (3, maxkeep)) { + if (!docombine) { + if (n1 == 0) + average[i] = blank + else { + sum = Mem$t[d[1]+k] + do j = 2, n1 + sum = sum + Mem$t[d[j]+k] + average[i] = sum / n1 + } + } + next + } + + # Compute average with the high and low rejected. + low = Mem$t[d[1]+k] + high = Mem$t[d[2]+k] + if (low > high) { + d1 = low + low = high + high = d1 + } + sum = 0. + do j = 3, n1 { + d1 = Mem$t[d[j]+k] + if (d1 < low) { + sum = sum + low + low = d1 + } else if (d1 > high) { + sum = sum + high + high = d1 + } else + sum = sum + d1 + } + a = sum / (n1 - 2) + sum = sum + low + high + + # Iteratively reject pixels and compute the final average if needed. + # Compact the data and keep track of the image IDs if needed. + + repeat { + n2 = n1 + if (doscale1) { + # Compute sigma corrected for scaling. + s = 0. + wp = w - 1 + do j = 1, n1 { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Mem$t[dp1] + l = Memi[mp1] + r = sqrt (max (one, (a + zeros[l]) / scales[l])) + s = s + ((d1 - a) / r) ** 2 + Memr[wp] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + wp = w - 1 + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + wp = wp + 1 + + d1 = Mem$t[dp1] + r = (d1 - a) / (s * Memr[wp]) + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + Memr[wp] = Memr[w+n1-1] + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } else { + # Compute the sigma without scale correction. + s = 0. + do j = 1, n1 + s = s + (Mem$t[d[j]+k] - a) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels. Save the residuals and data values. + if (s > 0.) { + for (j=1; j<=n1; j=j+1) { + dp1 = d[j] + k + d1 = Mem$t[dp1] + r = (d1 - a) / s + if (r < -lsigma || r > hsigma) { + Memr[resid+n1] = abs (r) + if (j < n1) { + dp2 = d[n1] + k + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[n1] + k + l = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = l + } + j = j - 1 + } + sum = sum - d1 + n1 = n1 - 1 + } + } + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } until (n1 == n2 || n1 <= max (2, maxkeep)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + if (n1 < maxkeep) { + nk = maxkeep + if (doscale1) { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + mp1 = m[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } else { + for (j=n1+1; j<=nk; j=j+1) { + dp1 = d[j] + k + r = Memr[resid+j] + jj = 0 + do l = j+1, n2 { + s = Memr[resid+l] + if (s < r + TOL) { + if (s > r - TOL) + jj = jj + 1 + else { + jj = 0 + Memr[resid+l] = r + r = s + dp2 = d[l] + k + d1 = Mem$t[dp1] + Mem$t[dp1] = Mem$t[dp2] + Mem$t[dp2] = d1 + if (keepids) { + mp1 = m[j] + k + mp2 = m[l] + k + s = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = s + } + } + } + } + sum = sum + Mem$t[dp1] + n1 = n1 + 1 + nk = max (nk, j+jj) + } + } + + # Recompute the average. + if (n1 > 1) + a = sum / n1 + } + + # Save the average if needed. + n[i] = n1 + if (!docombine) { + if (n1 > 0) + average[i] = a + else + average[i] = blank + } + } + + # Check if the data flag has to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + call sfree (sp) +end + + +# IC_MSIGCLIP -- Reject pixels using sigma clipping about the median + +procedure ic_msigclip$t (d, m, n, scales, zeros, nimages, npts, median) + +pointer d[nimages] # Data pointers +pointer m[nimages] # Image id pointers +int n[npts] # Number of good pixels +real scales[nimages] # Scales +real zeros[nimages] # Zeros +int nimages # Number of images +int npts # Number of output points per line +$if (datatype == sil) +real median[npts] # Median +$else +PIXEL median[npts] # Median +$endif + +int i, j, k, l, id, n1, n2, n3, nl, nh, nin, maxkeep +real r, s +pointer sp, resid, w, mp1, mp2 +$if (datatype == sil) +real med, one +data one /1.0/ +$else +PIXEL med, one +data one /1$f/ +$endif + +include "../icombine.com" + +begin + # If there are insufficient pixels go on to the combining + if (nkeep < 0) + maxkeep = max (0, nimages + nkeep) + else + maxkeep = min (nimages, nkeep) + if (nimages < max (MINCLIP, maxkeep+1) || dflag == D_NONE) { + docombine = true + return + } + + # Save the residuals and sigma scaling corrections if needed. + call smark (sp) + call salloc (resid, nimages+1, TY_REAL) + if (doscale1) + call salloc (w, nimages, TY_REAL) + + # Compute median and sigma and iteratively clip. + nin = n[1] + do i = 1, npts { + k = i - 1 + n1 = n[i] + if (nkeep < 0) + maxkeep = max (0, n1 + nkeep) + else + maxkeep = min (n1, nkeep) + nl = 1 + nh = n1 + + repeat { + n2 = n1 + n3 = nl + n1 / 2 + + if (n1 == 0) + med = blank + else if (mod (n1, 2) == 0) + med = (Mem$t[d[n3-1]+k] + Mem$t[d[n3]+k]) / 2. + else + med = Mem$t[d[n3]+k] + + if (n1 >= max (MINCLIP, maxkeep+1)) { + if (doscale1) { + # Compute the sigma with scaling correction. + s = 0. + do j = nl, nh { + l = Memi[m[j]+k] + r = sqrt (max (one, (med + zeros[l]) / scales[l])) + s = s + ((Mem$t[d[j]+k] - med) / r) ** 2 + Memr[w+j-1] = r + } + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Mem$t[d[nl]+k]) / (s * Memr[w+nl-1]) + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mem$t[d[nh]+k] - med) / (s * Memr[w+nh-1]) + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } else { + # Compute the sigma without scaling correction. + s = 0. + do j = nl, nh + s = s + (Mem$t[d[j]+k] - med) ** 2 + s = sqrt (s / (n1 - 1)) + + # Reject pixels and save the residuals. + if (s > 0.) { + for (; nl <= n2; nl = nl + 1) { + r = (med - Mem$t[d[nl]+k]) / s + if (r <= lsigma) + break + Memr[resid+nl] = r + n1 = n1 - 1 + } + for (; nh >= nl; nh = nh - 1) { + r = (Mem$t[d[nh]+k] - med) / s + if (r <= hsigma) + break + Memr[resid+nh] = r + n1 = n1 - 1 + } + } + } + } + } until (n1 == n2 || n1 < max (MINCLIP, maxkeep+1)) + + # If too many pixels are rejected add some back. + # All pixels with equal residuals are added back. + while (n1 < maxkeep) { + if (nl == 1) + nh = nh + 1 + else if (nh == n[i]) + nl = nl - 1 + else { + r = Memr[resid+nl-1] + s = Memr[resid+nh+1] + if (r < s) { + nl = nl - 1 + r = r + TOL + if (s <= r) + nh = nh + 1 + if (nl > 1) { + if (Memr[resid+nl-1] <= r) + nl = nl - 1 + } + } else { + nh = nh + 1 + s = s + TOL + if (r <= s) + nl = nl - 1 + if (nh < n2) { + if (Memr[resid+nh+1] <= s) + nh = nh + 1 + } + } + } + n1 = nh - nl + 1 + } + + # Only set median and reorder if needed + n[i] = n1 + if (n1 > 0 && nl > 1 && (combine != MEDIAN || grow >= 1.)) { + j = max (nl, n1 + 1) + if (keepids) { + do l = 1, min (n1, nl-1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + if (grow >= 1.) { + mp1 = m[l] + k + mp2 = m[j] + k + id = Memi[mp1] + Memi[mp1] = Memi[mp2] + Memi[mp2] = id + } else + Memi[m[l]+k] = Memi[m[j]+k] + j = j + 1 + } + } else { + do l = 1, min (n1, nl - 1) { + Mem$t[d[l]+k] = Mem$t[d[j]+k] + j = j + 1 + } + } + } + + if (combine == MEDIAN) + median[i] = med + } + + # Check if data flag needs to be reset for rejected pixels + if (dflag == D_ALL) { + do i = 1, npts { + if (n[i] != nin) { + dflag = D_MIX + break + } + } + } + + # Flag that the median has been computed. + if (combine == MEDIAN) + docombine = false + else + docombine = true + + call sfree (sp) +end +$endfor diff --git a/pkg/obsolete/imcombine/icsection.x b/pkg/obsolete/imcombine/icsection.x new file mode 100644 index 00000000..746c1f51 --- /dev/null +++ b/pkg/obsolete/imcombine/icsection.x @@ -0,0 +1,94 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctype.h> + +# IC_SECTION -- Parse an image section into its elements. +# 1. The default values must be set by the caller. +# 2. A null image section is OK. +# 3. The first nonwhitespace character must be '['. +# 4. The last interpreted character must be ']'. +# +# This procedure should be replaced with an IMIO procedure at some +# point. + +procedure ic_section (section, x1, x2, xs, ndim) + +char section[ARB] # Image section +int x1[ndim] # Starting pixel +int x2[ndim] # Ending pixel +int xs[ndim] # Step +int ndim # Number of dimensions + +int i, ip, a, b, c, temp, ctoi() +define error_ 99 + +begin + # Decode the section string. + ip = 1 + while (IS_WHITE(section[ip])) + ip = ip + 1 + if (section[ip] == '[') + ip = ip + 1 + else if (section[ip] == EOS) + return + else + goto error_ + + do i = 1, ndim { + while (IS_WHITE(section[ip])) + ip = ip + 1 + if (section[ip] == ']') + break + + # Default values + a = x1[i] + b = x2[i] + c = xs[i] + + # Get a:b:c. Allow notation such as "-*:c" + # (or even "-:c") where the step is obviously negative. + + if (ctoi (section, ip, temp) > 0) { # a + a = temp + if (section[ip] == ':') { + ip = ip + 1 + if (ctoi (section, ip, b) == 0) # a:b + goto error_ + } else + b = a + } else if (section[ip] == '-') { # -* + temp = a + a = b + b = temp + ip = ip + 1 + if (section[ip] == '*') + ip = ip + 1 + } else if (section[ip] == '*') # * + ip = ip + 1 + if (section[ip] == ':') { # ..:step + ip = ip + 1 + if (ctoi (section, ip, c) == 0) + goto error_ + else if (c == 0) + goto error_ + } + if (a > b && c > 0) + c = -c + + x1[i] = a + x2[i] = b + xs[i] = c + + while (IS_WHITE(section[ip])) + ip = ip + 1 + if (section[ip] == ',') + ip = ip + 1 + } + + if (section[ip] != ']') + goto error_ + + return +error_ + call error (0, "Error in image section specification") +end diff --git a/pkg/obsolete/imcombine/icsetout.x b/pkg/obsolete/imcombine/icsetout.x new file mode 100644 index 00000000..cdb69b43 --- /dev/null +++ b/pkg/obsolete/imcombine/icsetout.x @@ -0,0 +1,273 @@ +include <imhdr.h> +include <imset.h> +include <mwset.h> + +define OFFTYPES "|none|wcs|world|physical|grid|" +define FILE 0 +define NONE 1 +define WCS 2 +define WORLD 3 +define PHYSICAL 4 +define GRID 5 + +# IC_SETOUT -- Set output image size and offsets of input images. + +procedure ic_setout (in, out, offsets, nimages) + +pointer in[nimages] # Input images +pointer out[3] # Output images +int offsets[nimages,ARB] # Offsets +int nimages # Number of images + +int i, j, indim, outdim, mwdim, a, b, amin, bmax, fd, offtype +real val +bool reloff, flip, streq(), fp_equald() +pointer sp, str, fname +pointer pref, lref, wref, cd, ltm, coord, shift, axno, axval, section +pointer mw, ct, mw_openim(), mw_sctran(), immap() +int open(), fscan(), nscan(), mw_stati(), strlen(), strdic() +errchk mw_openim, mw_sctran, mw_ctrand, open, immap + +include "icombine.com" +define newscan_ 10 + +begin + call smark (sp) + call salloc (str, SZ_FNAME, TY_CHAR) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (lref, IM_MAXDIM, TY_DOUBLE) + call salloc (wref, IM_MAXDIM, TY_DOUBLE) + call salloc (cd, IM_MAXDIM*IM_MAXDIM, TY_DOUBLE) + call salloc (coord, IM_MAXDIM, TY_DOUBLE) + call salloc (shift, IM_MAXDIM, TY_REAL) + call salloc (axno, IM_MAXDIM, TY_INT) + call salloc (axval, IM_MAXDIM, TY_INT) + + # Check and set the image dimensionality. + indim = IM_NDIM(in[1]) + outdim = IM_NDIM(out[1]) + if (project) { + outdim = indim - 1 + IM_NDIM(out[1]) = outdim + } else { + do i = 1, nimages + if (IM_NDIM(in[i]) != outdim) { + call sfree (sp) + call error (1, "Image dimensions are not the same") + } + } + + # Set the reference point to that of the first image. + mw = mw_openim (in[1]) + mwdim = mw_stati (mw, MW_NPHYSDIM) + call mw_gwtermd (mw, Memd[lref], Memd[wref], Memd[cd], mwdim) + if (project) + Memd[lref+outdim] = 1 + + # Parse the user offset string. If "none" then there are no offsets. + # If "world" or "wcs" then set the offsets based on the world WCS. + # If "physical" then set the offsets based on the physical WCS. + # If "grid" then set the offsets based on the input grid parameters. + # If a file scan it. + + call clgstr ("offsets", Memc[fname], SZ_FNAME) + call sscan (Memc[fname]) + call gargwrd (Memc[fname], SZ_FNAME) + if (nscan() == 0) + offtype = NONE + else { + offtype = strdic (Memc[fname], Memc[str], SZ_FNAME, OFFTYPES) + if (offtype > 0 && !streq (Memc[fname], Memc[str])) + offtype = 0 + } + if (offtype == 0) + offtype = FILE + + switch (offtype) { + case NONE: + call aclri (offsets, outdim*nimages) + reloff = true + case WORLD, WCS: + do j = 1, outdim + offsets[1,j] = 0 + if (project) { + ct = mw_sctran (mw, "world", "logical", 0) + do i = 2, nimages { + Memd[wref+outdim] = i + call mw_ctrand (ct, Memd[wref], Memd[coord], indim) + do j = 1, outdim + offsets[i,j] = nint (Memd[lref+j-1] - Memd[coord+j-1]) + } + call mw_ctfree (ct) + call mw_close (mw) + } else { + do i = 2, nimages { + call mw_close (mw) + mw = mw_openim (in[i]) + ct = mw_sctran (mw, "world", "logical", 0) + call mw_ctrand (ct, Memd[wref], Memd[coord], indim) + do j = 1, outdim + offsets[i,j] = nint (Memd[lref+j-1] - Memd[coord+j-1]) + call mw_ctfree (ct) + } + } + reloff = true + case PHYSICAL: + call salloc (pref, IM_MAXDIM, TY_DOUBLE) + call salloc (ltm, IM_MAXDIM*IM_MAXDIM, TY_DOUBLE) + call salloc (section, SZ_FNAME, TY_CHAR) + + call mw_gltermd (mw, Memd[ltm], Memd[coord], indim) + do i = 2, nimages { + call mw_close (mw) + mw = mw_openim (in[i]) + call mw_gltermd (mw, Memd[cd], Memd[coord], indim) + call strcpy ("[", Memc[section], SZ_FNAME) + flip = false + do j = 0, indim*indim-1, indim+1 { + if (Memd[ltm+j] * Memd[cd+j] >= 0.) + call strcat ("*,", Memc[section], SZ_FNAME) + else { + call strcat ("-*,", Memc[section], SZ_FNAME) + flip = true + } + } + Memc[section+strlen(Memc[section])-1] = ']' + if (flip) { + call imstats (in[i], IM_IMAGENAME, Memc[fname], SZ_FNAME) + call strcat (Memc[section], Memc[fname], SZ_FNAME) + call imunmap (in[i]) + in[i] = immap (Memc[fname], READ_ONLY, TY_CHAR) + call mw_close (mw) + mw = mw_openim (in[i]) + call mw_gltermd (mw, Memd[cd], Memd[coord], indim) + do j = 0, indim*indim-1 + if (!fp_equald (Memd[ltm+j], Memd[cd+j])) + call error (1, + "Cannot match physical coordinates") + } + } + + call mw_close (mw) + mw = mw_openim (in[1]) + ct = mw_sctran (mw, "logical", "physical", 0) + call mw_ctrand (ct, Memd[lref], Memd[pref], indim) + call mw_ctfree (ct) + do j = 1, outdim + offsets[1,j] = 0 + if (project) { + ct = mw_sctran (mw, "physical", "logical", 0) + do i = 2, nimages { + Memd[pref+outdim] = i + call mw_ctrand (ct, Memd[pref], Memd[coord], indim) + do j = 1, outdim + offsets[i,j] = nint (Memd[lref+j-1] - Memd[coord+j-1]) + } + call mw_ctfree (ct) + call mw_close (mw) + } else { + do i = 2, nimages { + call mw_close (mw) + mw = mw_openim (in[i]) + ct = mw_sctran (mw, "physical", "logical", 0) + call mw_ctrand (ct, Memd[pref], Memd[coord], indim) + do j = 1, outdim + offsets[i,j] = nint (Memd[lref+j-1] - Memd[coord+j-1]) + call mw_ctfree (ct) + } + } + reloff = true + case GRID: + amin = 1 + do j = 1, outdim { + call gargi (a) + call gargi (b) + if (nscan() < 1+2*j) + break + do i = 1, nimages + offsets[i,j] = mod ((i-1)/amin, a) * b + amin = amin * a + } + reloff = true + case FILE: + reloff = true + fd = open (Memc[fname], READ_ONLY, TEXT_FILE) + do i = 1, nimages { +newscan_ if (fscan (fd) == EOF) + call error (1, "IMCOMBINE: Offset list too short") + call gargwrd (Memc[fname], SZ_FNAME) + if (Memc[fname] == '#') { + call gargwrd (Memc[fname], SZ_FNAME) + call strlwr (Memc[fname]) + if (streq (Memc[fname], "absolute")) + reloff = false + else if (streq (Memc[fname], "relative")) + reloff = true + goto newscan_ + } + call reset_scan () + do j = 1, outdim { + call gargr (val) + offsets[i,j] = nint (val) + } + if (nscan() < outdim) + call error (1, "IMCOMBINE: Error in offset list") + } + call close (fd) + } + + # Set the output image size and the aligned flag + aligned = true + do j = 1, outdim { + a = offsets[1,j] + b = IM_LEN(in[1],j) + a + amin = a + bmax = b + do i = 2, nimages { + a = offsets[i,j] + b = IM_LEN(in[i],j) + a + if (a != amin || b != bmax || !reloff) + aligned = false + amin = min (a, amin) + bmax = max (b, bmax) + } + IM_LEN(out[1],j) = bmax + if (reloff || amin < 0) { + do i = 1, nimages + offsets[i,j] = offsets[i,j] - amin + IM_LEN(out[1],j) = IM_LEN(out[1],j) - amin + } + } + + # Update the WCS. + if (project || !aligned || !reloff) { + call mw_close (mw) + mw = mw_openim (out[1]) + if (!aligned || !reloff) { + call mw_gltermd (mw, Memd[cd], Memd[lref], indim) + do i = 1, indim + Memd[lref+i-1] = Memd[lref+i-1] + offsets[1,i] + call mw_sltermd (mw, Memd[cd], Memd[lref], indim) + } + if (project) { + # Apply dimensional reduction. + i = mw_stati (mw, MW_NPHYSDIM) + call mw_gaxmap (mw, Memi[axno], Memi[axval], i) + do j = 0, i-1 { + if (Memi[axno+j] <= outdim) { + next + } else if (Memi[axno+j] > outdim+1) { + Memi[axno+j] = Memi[axno+j] - 1 + } else { + Memi[axno+j] = 0 + Memi[axval+j] = 0 + } + } + call mw_saxmap (mw, Memi[axno], Memi[axval], i) + } + call mw_saveim (mw, out) + } + call mw_close (mw) + + call sfree (sp) +end diff --git a/pkg/obsolete/imcombine/icsigma.gx b/pkg/obsolete/imcombine/icsigma.gx new file mode 100644 index 00000000..81e536c4 --- /dev/null +++ b/pkg/obsolete/imcombine/icsigma.gx @@ -0,0 +1,115 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + +$for (sird) +# IC_SIGMA -- Compute the sigma image line. +# The estimated sigma includes a correction for the finite population. +# Weights are used if desired. + +procedure ic_sigma$t (d, m, n, wts, npts, average, sigma) + +pointer d[ARB] # Data pointers +pointer m[ARB] # Image ID pointers +int n[npts] # Number of points +real wts[ARB] # Weights +int npts # Number of output points per line +$if (datatype == sil) +real average[npts] # Average +real sigma[npts] # Sigma line (returned) +$else +PIXEL average[npts] # Average +PIXEL sigma[npts] # Sigma line (returned) +$endif + +int i, j, k, n1 +real wt, sigcor, sumwt +$if (datatype == sil) +real a, sum +$else +PIXEL a, sum +$endif + +include "../icombine.com" + +begin + if (dflag == D_ALL) { + n1 = n[1] + if (dowts) { + if (n1 > 1) + sigcor = real (n1) / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Mem$t[d[1]+k] - a) ** 2 * wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Mem$t[d[j]+k] - a) ** 2 * wt + } + sigma[i] = sqrt (sum * sigcor) + } + } else { + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + do i = 1, npts { + k = i - 1 + a = average[i] + sum = (Mem$t[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Mem$t[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } + } + } else if (dflag == D_NONE) { + do i = 1, npts + sigma[i] = blank + } else { + if (dowts) { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = real (n1) / real (n1 -1) + else + sigcor = 1 + a = average[i] + wt = wts[Memi[m[1]+k]] + sum = (Mem$t[d[1]+k] - a) ** 2 * wt + sumwt = wt + do j = 2, n1 { + wt = wts[Memi[m[j]+k]] + sum = sum + (Mem$t[d[j]+k] - a) ** 2 * wt + sumwt = sumwt + wt + } + sigma[i] = sqrt (sum / sumwt * sigcor) + } else + sigma[i] = blank + } + } else { + do i = 1, npts { + n1 = n[i] + if (n1 > 0) { + k = i - 1 + if (n1 > 1) + sigcor = 1. / real (n1 - 1) + else + sigcor = 1. + a = average[i] + sum = (Mem$t[d[1]+k] - a) ** 2 + do j = 2, n1 + sum = sum + (Mem$t[d[j]+k] - a) ** 2 + sigma[i] = sqrt (sum * sigcor) + } else + sigma[i] = blank + } + } + } +end +$endfor diff --git a/pkg/obsolete/imcombine/icsort.gx b/pkg/obsolete/imcombine/icsort.gx new file mode 100644 index 00000000..e124da15 --- /dev/null +++ b/pkg/obsolete/imcombine/icsort.gx @@ -0,0 +1,386 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +define LOGPTR 32 # log2(maxpts) (4e9) + +$for (sird) +# IC_SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. + +procedure ic_sort$t (a, b, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +PIXEL b[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +PIXEL pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR] +define swap {temp=$1;$1=$2;$2=temp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix + b[i] = Mem$t[a[i]+l] + + # Special cases + $if (datatype == x) + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (abs (temp) < abs (pivot)) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (abs (temp) < abs (pivot)) { # bac|bca|cba + if (abs (temp) < abs (temp3)) { # bac|bca + b[1] = temp + if (abs (pivot) < abs (temp3)) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (abs (temp3) < abs (temp)) { # acb|cab + b[3] = temp + if (abs (pivot) < abs (temp3)) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + $else + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) # bac + b[2] = pivot + else { # bca + b[2] = temp3 + b[3] = pivot + } + } else { # cba + b[1] = temp3 + b[3] = pivot + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) # acb + b[2] = temp3 + else { # cab + b[1] = temp3 + b[2] = pivot + } + } else + next + } + goto copy_ + } + $endif + + # General case + do i = 1, npix + b[i] = Mem$t[a[i]+l] + + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]) + pivot = b[j] # pivot line + + while (i < j) { + $if (datatype == x) + for (i=i+1; abs(b[i]) < abs(pivot); i=i+1) + $else + for (i=i+1; b[i] < pivot; i=i+1) + $endif + ; + for (j=j-1; j > i; j=j-1) + $if (datatype == x) + if (abs(b[j]) <= abs(pivot)) + $else + if (b[j] <= pivot) + $endif + break + if (i < j) # out of order pair + swap (b[i], b[j]) # interchange elements + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix + Mem$t[a[i]+l] = b[i] + } +end + + +# IC_2SORT -- Quicksort. This is based on the VOPS asrt except that +# the input is an array of pointers to image lines and the sort is done +# across the image lines at each point along the lines. The number of +# valid pixels at each point is allowed to vary. The cases of 1, 2, and 3 +# pixels per point are treated specially. A second integer set of +# vectors is sorted. + +procedure ic_2sort$t (a, b, c, d, nvecs, npts) + +pointer a[ARB] # pointer to input vectors +PIXEL b[ARB] # work array +pointer c[ARB] # pointer to associated integer vectors +int d[ARB] # work array +int nvecs[npts] # number of vectors +int npts # number of points in vectors + +PIXEL pivot, temp, temp3 +int i, j, k, l, p, npix, lv[LOGPTR], uv[LOGPTR], itemp +define swap {temp=$1;$1=$2;$2=temp} +define iswap {itemp=$1;$1=$2;$2=itemp} +define copy_ 10 + +begin + do l = 0, npts-1 { + npix = nvecs[l+1] + if (npix <= 1) + next + + do i = 1, npix { + b[i] = Mem$t[a[i]+l] + d[i] = Memi[c[i]+l] + } + + # Special cases + $if (datatype == x) + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (abs (temp) < abs (pivot)) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (abs (temp) < abs (pivot)) { # bac|bca|cba + if (abs (temp) < abs (temp3)) { # bac|bca + b[1] = temp + if (abs (pivot) < abs (temp3)) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (abs (temp3) < abs (temp)) { # acb|cab + b[3] = temp + if (abs (pivot) < abs (temp3)) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + $else + if (npix <= 3) { + pivot = b[1] + temp = b[2] + if (npix == 2) { + if (temp < pivot) { + b[1] = temp + b[2] = pivot + iswap (d[1], d[2]) + } else + next + } else { + temp3 = b[3] + if (temp < pivot) { # bac|bca|cba + if (temp < temp3) { # bac|bca + b[1] = temp + if (pivot < temp3) { # bac + b[2] = pivot + iswap (d[1], d[2]) + } else { # bca + b[2] = temp3 + b[3] = pivot + itemp = d[2] + d[2] = d[3] + d[3] = d[1] + d[1] = itemp + } + } else { # cba + b[1] = temp3 + b[3] = pivot + iswap (d[1], d[3]) + } + } else if (temp3 < temp) { # acb|cab + b[3] = temp + if (pivot < temp3) { # acb + b[2] = temp3 + iswap (d[2], d[3]) + } else { # cab + b[1] = temp3 + b[2] = pivot + itemp = d[2] + d[2] = d[1] + d[1] = d[3] + d[3] = itemp + } + } else + next + } + goto copy_ + } + $endif + + # General case + lv[1] = 1 + uv[1] = npix + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy do loop to trigger the Fortran optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select as the pivot the element at the center of the + # array, to avoid quadratic behavior on an already + # sorted array. + + k = (lv[p] + uv[p]) / 2 + swap (b[j], b[k]); swap (d[j], d[k]) + pivot = b[j] # pivot line + + while (i < j) { + $if (datatype == x) + for (i=i+1; abs(b[i]) < abs(pivot); i=i+1) + $else + for (i=i+1; b[i] < pivot; i=i+1) + $endif + ; + for (j=j-1; j > i; j=j-1) + $if (datatype == x) + if (abs(b[j]) <= abs(pivot)) + $else + if (b[j] <= pivot) + $endif + break + if (i < j) { # out of order pair + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + } + } + + j = uv[p] # move pivot to position i + swap (b[i], b[j]) # interchange elements + swap (d[i], d[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + p = p + 1 # push onto stack + } + } + +copy_ + do i = 1, npix { + Mem$t[a[i]+l] = b[i] + Memi[c[i]+l] = d[i] + } + } +end +$endfor diff --git a/pkg/obsolete/imcombine/icstat.gx b/pkg/obsolete/imcombine/icstat.gx new file mode 100644 index 00000000..f2b65089 --- /dev/null +++ b/pkg/obsolete/imcombine/icstat.gx @@ -0,0 +1,237 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include "../icombine.h" + +define NMAX 10000 # Maximum number of pixels to sample + +$for (sird) +# IC_STAT -- Compute image statistics within specified section. +# The image section is relative to a reference image which may be +# different than the input image and may have an offset. Only a +# subsample of pixels is used. Masked and thresholded pixels are +# ignored. Only the desired statistics are computed to increase +# efficiency. + +procedure ic_stat$t (im, imref, section, offsets, image, nimages, + domode, domedian, domean, mode, median, mean) + +pointer im # Data image +pointer imref # Reference image for image section +char section[ARB] # Image section +int offsets[nimages,ARB] # Image section offset from data to reference +int image # Image index (for mask I/O) +int nimages # Number of images in offsets. +bool domode, domedian, domean # Statistics to compute +real mode, median, mean # Statistics + +int i, j, ndim, n, nv +real a +pointer sp, v1, v2, dv, va, vb +pointer data, mask, dp, lp, mp, imgnl$t() +PIXEL ic_mode$t() +$if (datatype == irs) +real asum$t() +$endif +$if (datatype == dl) +double asum$t() +$endif +$if (datatype == x) +complex asum$t() +$endif + + +include "../icombine.com" + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call salloc (dv, IM_MAXDIM, TY_LONG) + call salloc (va, IM_MAXDIM, TY_LONG) + call salloc (vb, IM_MAXDIM, TY_LONG) + + # Determine the image section parameters. This must be in terms of + # the data image pixel coordinates though the section may be specified + # in terms of the reference image coordinates. Limit the number of + # pixels in each dimension to a maximum. + + ndim = IM_NDIM(im) + if (project) + ndim = ndim - 1 + call amovki (1, Memi[v1], IM_MAXDIM) + call amovki (1, Memi[va], IM_MAXDIM) + call amovki (1, Memi[dv], IM_MAXDIM) + call amovi (IM_LEN(imref,1), Memi[vb], ndim) + call ic_section (section, Memi[va], Memi[vb], Memi[dv], ndim) + if (im != imref) + do i = 1, ndim { + Memi[va+i-1] = Memi[va+i-1] - offsets[image,i] + Memi[vb+i-1] = Memi[vb+i-1] - offsets[image,i] + } + + do j = 1, 10 { + n = 1 + do i = 0, ndim-1 { + Memi[v1+i] = max (1, min (Memi[va+i], Memi[vb+i])) + Memi[v2+i] = min (IM_LEN(im,i+1), max (Memi[va+i], Memi[vb+i])) + Memi[dv+i] = j + nv = max (1, (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + Memi[v2+i] = Memi[v1+i] + (nv - 1) * Memi[dv+i] + n = n * nv + } + if (n < NMAX) + break + } + + call amovl (Memi[v1], Memi[va], IM_MAXDIM) + Memi[va] = 1 + if (project) + Memi[va+ndim] = image + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + + # Accumulate the pixel values within the section. Masked pixels and + # thresholded pixels are ignored. + + call salloc (data, n, TY_PIXEL) + dp = data + while (imgnl$t (im, lp, Memi[vb]) != EOF) { + call ic_mget1 (im, image, offsets[image,1], Memi[va], mask) + lp = lp + Memi[v1] - 1 + if (dflag == D_ALL) { + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + a = Mem$t[lp] + if (a >= lthresh && a <= hthresh) { + Mem$t[dp] = a + dp = dp + 1 + } + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + Mem$t[dp] = Mem$t[lp] + dp = dp + 1 + lp = lp + Memi[dv] + } + } + } else if (dflag == D_MIX) { + mp = mask + Memi[v1] - 1 + if (dothresh) { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + a = Mem$t[lp] + if (a >= lthresh && a <= hthresh) { + Mem$t[dp] = a + dp = dp + 1 + } + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } else { + do i = Memi[v1], Memi[v2], Memi[dv] { + if (Memi[mp] == 0) { + Mem$t[dp] = Mem$t[lp] + dp = dp + 1 + } + mp = mp + Memi[dv] + lp = lp + Memi[dv] + } + } + } + for (i=2; i<=ndim; i=i+1) { + Memi[va+i-1] = Memi[va+i-1] + Memi[dv+i-1] + if (Memi[va+i-1] <= Memi[v2+i-1]) + break + Memi[va+i-1] = Memi[v1+i-1] + } + if (i > ndim) + break + call amovl (Memi[va], Memi[vb], IM_MAXDIM) + } + + n = dp - data + if (n < 1) { + call sfree (sp) + call error (1, "Image section contains no pixels") + } + + # Compute only statistics needed. + if (domode || domedian) { + call asrt$t (Mem$t[data], Mem$t[data], n) + mode = ic_mode$t (Mem$t[data], n) + median = Mem$t[data+n/2-1] + } + if (domean) + mean = asum$t (Mem$t[data], n) / n + + call sfree (sp) +end + + +define NMIN 10 # Minimum number of pixels for mode calculation +define ZRANGE 0.8 # Fraction of pixels about median to use +define ZSTEP 0.01 # Step size for search for mode +define ZBIN 0.1 # Bin size for mode. + +# IC_MODE -- Compute mode of an array. The mode is found by binning +# with a bin size based on the data range over a fraction of the +# pixels about the median and a bin step which may be smaller than the +# bin size. If there are too few points the median is returned. +# The input array must be sorted. + +PIXEL procedure ic_mode$t (a, n) + +PIXEL a[n] # Data array +int n # Number of points + +int i, j, k, nmax +real z1, z2, zstep, zbin +PIXEL mode +bool fp_equalr() + +begin + if (n < NMIN) + return (a[n/2]) + + # Compute the mode. The array must be sorted. Consider a + # range of values about the median point. Use a bin size which + # is ZBIN of the range. Step the bin limits in ZSTEP fraction of + # the bin size. + + i = 1 + n * (1. - ZRANGE) / 2. + j = 1 + n * (1. + ZRANGE) / 2. + z1 = a[i] + z2 = a[j] + if (fp_equalr (z1, z2)) { + mode = z1 + return (mode) + } + + zstep = ZSTEP * (z2 - z1) + zbin = ZBIN * (z2 - z1) + $if (datatype == sil) + zstep = max (1., zstep) + zbin = max (1., zbin) + $endif + + z1 = z1 - zstep + k = i + nmax = 0 + repeat { + z1 = z1 + zstep + z2 = z1 + zbin + for (; i < j && a[i] < z1; i=i+1) + ; + for (; k < j && a[k] < z2; k=k+1) + ; + if (k - i > nmax) { + nmax = k - i + mode = a[(i+k)/2] + } + } until (k >= j) + + return (mode) +end +$endfor diff --git a/pkg/obsolete/imcombine/mkpkg b/pkg/obsolete/imcombine/mkpkg new file mode 100644 index 00000000..4b6c120b --- /dev/null +++ b/pkg/obsolete/imcombine/mkpkg @@ -0,0 +1,54 @@ +# Make the IMCOMBINE Task. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +generic: + $set GEN = "$$generic -k" + + $ifolder (generic/icaclip.x, icaclip.gx) + $(GEN) icaclip.gx -o generic/icaclip.x $endif + $ifolder (generic/icaverage.x, icaverage.gx) + $(GEN) icaverage.gx -o generic/icaverage.x $endif + $ifolder (generic/iccclip.x, iccclip.gx) + $(GEN) iccclip.gx -o generic/iccclip.x $endif + $ifolder (generic/icgdata.x, icgdata.gx) + $(GEN) icgdata.gx -o generic/icgdata.x $endif + $ifolder (generic/icgrow.x, icgrow.gx) + $(GEN) icgrow.gx -o generic/icgrow.x $endif + $ifolder (generic/icmedian.x, icmedian.gx) + $(GEN) icmedian.gx -o generic/icmedian.x $endif + $ifolder (generic/icmm.x, icmm.gx) + $(GEN) icmm.gx -o generic/icmm.x $endif + $ifolder (generic/icombine.x, icombine.gx) + $(GEN) icombine.gx -o generic/icombine.x $endif + $ifolder (generic/icpclip.x, icpclip.gx) + $(GEN) icpclip.gx -o generic/icpclip.x $endif + $ifolder (generic/icsclip.x, icsclip.gx) + $(GEN) icsclip.gx -o generic/icsclip.x $endif + $ifolder (generic/icsigma.x, icsigma.gx) + $(GEN) icsigma.gx -o generic/icsigma.x $endif + $ifolder (generic/icsort.x, icsort.gx) + $(GEN) icsort.gx -o generic/icsort.x $endif + $ifolder (generic/icstat.x, icstat.gx) + $(GEN) icstat.gx -o generic/icstat.x $endif + ; + +libpkg.a: + $ifeq (USE_GENERIC, yes) $call generic $endif + + @generic + + icimstack.x <error.h> <imhdr.h> + iclog.x icmask.com icombine.com icombine.h <imhdr.h> <imset.h>\ + <mach.h> + icmask.x icmask.com icombine.com icombine.h <imhdr.h> <pmset.h> + icrmasks.x <imhdr.h> + icscale.x icombine.com icombine.h <error.h> <imhdr.h> <imset.h> + icsection.x <ctype.h> + icsetout.x icombine.com <imhdr.h> <mwset.h> <imset.h> + t_imcombine.x icombine.com icombine.h <error.h> <imhdr.h> <mach.h> \ + <syserr.h> <pmset.h> + ; diff --git a/pkg/obsolete/imcombine/t_imcombine.x b/pkg/obsolete/imcombine/t_imcombine.x new file mode 100644 index 00000000..5b2e5026 --- /dev/null +++ b/pkg/obsolete/imcombine/t_imcombine.x @@ -0,0 +1,501 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <error.h> +include <syserr.h> +include <mach.h> +include <pmset.h> +include "icombine.h" + + +# T_IMCOMBINE - This task combines a list of images into an output image +# and an optional sigma image. There are many combining options from +# which to choose. + +procedure t_imcombine () + +pointer sp, input, output, rmask, sigma, plfile, logfile +int ilist, olist, rlist, slist, plist, n + +bool clgetb() +real clgetr() +int clgwrd(), clgeti(), imtopenp(), imtgetim(), imtlen() + +include "icombine.com" + +begin + call smark (sp) + call salloc (input, SZ_FNAME, TY_CHAR) + call salloc (output, SZ_FNAME, TY_CHAR) + call salloc (rmask, SZ_FNAME, TY_CHAR) + call salloc (plfile, SZ_FNAME, TY_CHAR) + call salloc (sigma, SZ_FNAME, TY_CHAR) + call salloc (gain, SZ_FNAME, TY_CHAR) + call salloc (rdnoise, SZ_FNAME, TY_CHAR) + call salloc (snoise, SZ_FNAME, TY_CHAR) + call salloc (logfile, SZ_FNAME, TY_CHAR) + + # Get task parameters. Some additional parameters are obtained later. + ilist = imtopenp ("input") + olist = imtopenp ("output") + rlist = imtopenp ("rejmask") + plist = imtopenp ("plfile") + slist = imtopenp ("sigma") + call clgstr ("logfile", Memc[logfile], SZ_FNAME) + + project = clgetb ("project") + combine = clgwrd ("combine", Memc[input], SZ_FNAME, COMBINE) + reject = clgwrd ("reject", Memc[input], SZ_FNAME, REJECT) + blank = clgetr ("blank") + call clgstr ("gain", Memc[gain], SZ_FNAME) + call clgstr ("rdnoise", Memc[rdnoise], SZ_FNAME) + call clgstr ("snoise", Memc[snoise], SZ_FNAME) + lthresh = clgetr ("lthreshold") + hthresh = clgetr ("hthreshold") + lsigma = clgetr ("lsigma") + hsigma = clgetr ("hsigma") + pclip = clgetr ("pclip") + flow = clgetr ("nlow") + fhigh = clgetr ("nhigh") + nkeep = clgeti ("nkeep") + grow = clgetr ("grow") + mclip = clgetb ("mclip") + sigscale = clgetr ("sigscale") + + # Check lists. + n = imtlen (ilist) + if (n == 0) + call error (1, "No input images to combine") + if (project) { + if (imtlen (olist) != n) + call error (1, "Wrong number of images in output list") + if (imtlen (rlist) != 0 && imtlen (rlist) != n) + call error (1, "Wrong number of masks in rejection mask list") + if (imtlen (plist) > 0 && imtlen (plist) != n) + call error (1, "Wrong number of masks in output mask list") + if (imtlen (slist) > 0 && imtlen (slist) != n) + call error (1, "Wrong number of images in output sigma list") + } else { + if (imtlen (olist) != 1) + call error (1, "Wrong number of images in output list") + if (imtlen (rlist) > 1) + call error (1, "Wrong number of masks in rejection mask list") + if (imtlen (plist) > 1) + call error (1, "Wrong number of masks in output mask list") + if (imtlen (slist) > 1) + call error (1, "Wrong number of images in output sigma list") + } + + # Check parameters, map INDEFs, and set threshold flag + if (pclip == 0. && reject == PCLIP) + call error (1, "Pclip parameter may not be zero") + if (IS_INDEFR (blank)) + blank = 0. + if (IS_INDEFR (lsigma)) + lsigma = MAX_REAL + if (IS_INDEFR (hsigma)) + hsigma = MAX_REAL + if (IS_INDEFR (pclip)) + pclip = -0.5 + if (IS_INDEFR (flow)) + flow = 0 + if (IS_INDEFR (fhigh)) + fhigh = 0 + if (IS_INDEFR (grow)) + grow = 0. + if (IS_INDEF (sigscale)) + sigscale = 0. + + if (IS_INDEF(lthresh) && IS_INDEF(hthresh)) + dothresh = false + else { + dothresh = true + if (IS_INDEF(lthresh)) + lthresh = -MAX_REAL + if (IS_INDEF(hthresh)) + hthresh = MAX_REAL + } + + # Loop through image lists. Note that if not projecting then + # the input and rejmask lists will be exhausted by IMCOMBINE. + + while (imtgetim (ilist, Memc[input], SZ_FNAME) != EOF) { + if (imtgetim (olist, Memc[output], SZ_FNAME) == EOF) { + if (project) { + call eprintf ("IMCOMBINE: No output image for %s\n") + call pargstr (Memc[input]) + next + } else { + call eprintf ("IMCOMBINE: No output image\n") + call pargstr (Memc[input]) + break + } + } + if (imtgetim (rlist, Memc[rmask], SZ_FNAME) == EOF) + Memc[rmask] = EOS + if (imtgetim (plist, Memc[plfile], SZ_FNAME) == EOF) + Memc[plfile] = EOS + if (imtgetim (slist, Memc[sigma], SZ_FNAME) == EOF) + Memc[sigma] = EOS + + iferr (call icombine (ilist, Memc[input], Memc[output], + Memc[rmask], Memc[plfile], Memc[sigma], Memc[logfile], NO)) + call erract (EA_WARN) + } + + call imtclose (ilist) + call imtclose (olist) + call imtclose (rlist) + call imtclose (plist) + call imtclose (slist) + call sfree (sp) +end + + +# IMCOMBINE -- Combine input list or image. +# This procedure maps the images, sets the output dimensions and datatype, +# opens the logfile, and sets IMIO parameters. It attempts to adjust +# buffer sizes and memory requirements for maximum efficiency. + +procedure icombine (list, input, output, rmask, plfile, sigma, + logfile, stack) + +int list # List of input images +char input[ARB] # Input image +char output[ARB] # Output image +char rmask[ARB] # Rejection mask +char plfile[ARB] # Output pixel list file +char sigma[ARB] # Sigma image (optional) +char logfile[ARB] # Logfile (optional) +int stack # Stack input images? + +char errstr[SZ_LINE] +int i, j, nimages, intype, bufsize, maxsize, memory, oldsize, stack1, err +pointer sp, in, out[4], icm, offsets, key, tmp + +char clgetc() +int imtlen(), imtgetim(), imtrgetim(), getdatatype() +int begmem(), errget(), open(), ty_max(), sizeof() +pointer immap(), ic_pmmap() +errchk ic_imstack, immap, ic_pmmap, ic_setout + +include "icombine.com" + +define retry_ 98 + +begin + # Map the input images. + bufsize = 0 + stack1 = stack + +retry_ + iferr { + call smark (sp) + + in = NULL + out[1] = NULL + out[2] = NULL + out[3] = NULL + out[4] = NULL + icm = NULL + logfd = NULL + + # Stack the input images. + if (stack1 == YES) { + call mktemp ("tmp", input, SZ_FNAME) + call imtrew (list) + call ic_imstack (list, input) + project = true + } + + # Open the input image(s). + nimages = 0 + if (project) { + tmp = immap (input, READ_ONLY, 0); out[1] = tmp + if (IM_NDIM(out[1]) == 1) + call error (1, "Can't project one dimensional images") + nimages = IM_LEN(out[1],IM_NDIM(out[1])) + call salloc (in, nimages, TY_POINTER) + call amovki (out[1], Memi[in], nimages) + } else { + call salloc (in, imtlen(list), TY_POINTER) + call amovki (NULL, Memi[in], imtlen(list)) + call imtrew (list) + while (imtgetim (list, input, SZ_FNAME)!=EOF) { + tmp = immap (input, READ_ONLY, 0) + Memi[in+nimages] = tmp + nimages = nimages + 1 + } + } + + # Check if there are no images. + if (nimages == 0) + call error (1, "No input images to combine") + + # Convert the pclip parameter to a number of pixels rather than + # a fraction. This number stays constant even if pixels are + # rejected. The number of low and high pixel rejected, however, + # are converted to a fraction of the valid pixels. + + if (reject == PCLIP) { + i = (nimages - 1) / 2. + if (abs (pclip) < 1.) + pclip = pclip * i + if (pclip < 0.) + pclip = min (-1, max (-i, int (pclip))) + else + pclip = max (1, min (i, int (pclip))) + } + + if (reject == MINMAX) { + if (flow >= 1) + flow = flow / nimages + if (fhigh >= 1) + fhigh = fhigh / nimages + i = flow * nimages + j = fhigh * nimages + if (i + j == 0) + reject = NONE + else if (i + j >= nimages) + call error (1, "Bad minmax rejection parameters") + } + + # Map the output image and set dimensions and offsets. + tmp = immap (output, NEW_COPY, Memi[in]); out[1] = tmp + if (stack1 == YES) { + call salloc (key, SZ_FNAME, TY_CHAR) + do i = 1, nimages { + call sprintf (Memc[key], SZ_FNAME, "stck%04d") + call pargi (i) + call imdelf (out[1], Memc[key]) + } + } + call salloc (offsets, nimages*IM_NDIM(out[1]), TY_INT) + call ic_setout (Memi[in], out, Memi[offsets], nimages) + + # Determine the highest precedence datatype and set output datatype. + intype = IM_PIXTYPE(Memi[in]) + do i = 2, nimages + intype = ty_max (intype, IM_PIXTYPE(Memi[in+i-1])) + IM_PIXTYPE(out[1]) = getdatatype (clgetc ("outtype")) + if (IM_PIXTYPE(out[1]) == ERR) + IM_PIXTYPE(out[1]) = intype + + # Open rejection masks + if (rmask[1] != EOS) { + tmp = ic_pmmap (rmask, NEW_COPY, out[1]); out[4] = tmp + IM_NDIM(out[4]) = IM_NDIM(out[4]) + 1 + IM_LEN(out[4],IM_NDIM(out[4])) = nimages + if (!project) { + if (key == NULL) + call salloc (key, SZ_FNAME, TY_CHAR) + do i = 1, nimages { + j = imtrgetim (list, i, input, SZ_FNAME) + call sprintf (Memc[key], SZ_FNAME, "mask%04d") + call pargi (i) + call imastr (out[4], Memc[key], input) + } + } + } else + out[4] = NULL + + # Open pixel list file if given. + if (plfile[1] != EOS) { + tmp = ic_pmmap (plfile, NEW_COPY, out[1]); out[2] = tmp + } else + out[2] = NULL + + # Open the sigma image if given. + if (sigma[1] != EOS) { + tmp = immap (sigma, NEW_COPY, out[1]); out[3] = tmp + IM_PIXTYPE(out[3]) = ty_max (TY_REAL, IM_PIXTYPE(out[1])) + call sprintf (IM_TITLE(out[3]), SZ_IMTITLE, + "Combine sigma images for %s") + call pargstr (output) + } else + out[3] = NULL + + # Open masks. + call ic_mopen (Memi[in], out, nimages) + icm = nimages + + # Open the log file. + logfd = NULL + if (logfile[1] != EOS) { + iferr (logfd = open (logfile, APPEND, TEXT_FILE)) { + logfd = NULL + call erract (EA_WARN) + } + } + + if (bufsize == 0) { + # Set initial IMIO buffer size based on the number of images + # and maximum amount of working memory available. The buffer + # size may be adjusted later if the task runs out of memory. + # The FUDGE factor is used to allow for the size of the + # program, memory allocator inefficiencies, and any other + # memory requirements besides IMIO. + + bufsize = 1 + do i = 1, IM_NDIM(out[1]) + bufsize = bufsize * IM_LEN(out[1],i) + bufsize = bufsize * sizeof (intype) + bufsize = min (bufsize, DEFBUFSIZE) + memory = begmem ((nimages + 1) * bufsize, oldsize, maxsize) + memory = min (memory, int (FUDGE * maxsize)) + bufsize = memory / (nimages + 1) + } + + # Combine the images. If an out of memory error occurs close all + # images and files, divide the IMIO buffer size in half and try + # again. The integer types are not support because scaling is + # done on the input data vectors. + + switch (ty_max (intype, IM_PIXTYPE(out[1]))) { + case TY_SHORT: + call icombines (Memi[in], out, Memi[offsets], nimages, bufsize) + case TY_USHORT, TY_INT, TY_LONG: + call icombinei (Memi[in], out, Memi[offsets], nimages, bufsize) + case TY_DOUBLE: + call icombined (Memi[in], out, Memi[offsets], nimages, bufsize) + case TY_COMPLEX: + call error (1, "Complex images not allowed") + default: + call icombiner (Memi[in], out, Memi[offsets], nimages, bufsize) + } + } then { + err = errget (errstr, SZ_LINE) + if (icm != NULL) + call ic_mclose (nimages) + if (!project) { + do j = 2, nimages { + if (Memi[in+j-1] != NULL) + call imunmap (Memi[in+j-1]) + } + } + if (out[2] != NULL) + call imunmap (out[2]) + if (out[3] != NULL) { + call imunmap (out[3]) + call imdelete (sigma) + } + if (out[4] != NULL) + call imunmap (out[4]) + if (out[1] != NULL) { + call imunmap (out[1]) + call imdelete (output) + } + if (Memi[in] != NULL) + call imunmap (Memi[in]) + if (logfd != NULL) + call close (logfd) + + switch (err) { + case SYS_MFULL: + bufsize = bufsize / 2 + call sfree (sp) + goto retry_ + case SYS_FTOOMANYFILES, SYS_IKIOPEN, SYS_IKIOPIX: + if (!project) { + stack1 = YES + goto retry_ + } + if (stack1 == YES) + call imdelete (input) + call fixmem (oldsize) + call sfree (sp) + call error (err, errstr) + default: + if (stack1 == YES) + call imdelete (input) + call fixmem (oldsize) + call sfree (sp) + call error (err, errstr) + } + } + + # Unmap all the images, close the log file, and restore memory. + # The input images must be unmapped first to insure that there + # is a FD for the output images since the headers are opened to + # update them. However, the order of the NEW_COPY pointers must + # be preserved. + + if (!project) { + do i = 2, nimages + if (Memi[in+i-1] != NULL) + call imunmap (Memi[in+i-1]) + } + if (out[2] != NULL) + call imunmap (out[2]) + if (out[3] != NULL) + call imunmap (out[3]) + if (out[4] != NULL) + call imunmap (out[4]) + if (out[1] != NULL) + call imunmap (out[1]) + if (Memi[in] != NULL) + call imunmap (Memi[in]) + if (stack1 == YES) + call imdelete (input) + if (logfd != NULL) + call close (logfd) + if (icm != NULL) + call ic_mclose (nimages) + call fixmem (oldsize) + call sfree (sp) +end + + +# TY_MAX -- Return the datatype of highest precedence. + +int procedure ty_max (type1, type2) + +int type1, type2 # Datatypes + +int i, j, type, order[8] +data order/TY_SHORT,TY_USHORT,TY_INT,TY_LONG,TY_REAL,TY_DOUBLE,TY_COMPLEX,TY_REAL/ + +begin + for (i=1; (i<=7) && (type1!=order[i]); i=i+1) + ; + for (j=1; (j<=7) && (type2!=order[j]); j=j+1) + ; + type = order[max(i,j)] + + # Special case of mixing short and unsigned short. + if (type == TY_USHORT && type1 != type2) + type = TY_INT + + return (type) +end + + +# IC_PMMAP -- Map pixel mask. + +pointer procedure ic_pmmap (fname, mode, refim) + +char fname[ARB] # Mask name +int mode # Image mode +pointer refim # Reference image +pointer pm # IMIO pointer (returned) + +int i, fnextn() +pointer sp, extn, immap() +bool streq() + +begin + call smark (sp) + call salloc (extn, SZ_FNAME, TY_CHAR) + + i = fnextn (fname, Memc[extn], SZ_FNAME) + if (streq (Memc[extn], "pl")) + pm = immap (fname, mode, refim) + else { + call strcpy (fname, Memc[extn], SZ_FNAME) + call strcat (".pl", Memc[extn], SZ_FNAME) + pm = immap (Memc[extn], mode, refim) + } + + call sfree (sp) + return (pm) +end diff --git a/pkg/obsolete/imtitle.par b/pkg/obsolete/imtitle.par new file mode 100644 index 00000000..be55db05 --- /dev/null +++ b/pkg/obsolete/imtitle.par @@ -0,0 +1,4 @@ +#IMTITLE -- Change the title of an image. + +image,f,a,,,,Image to be changed +title,s,a,,,,New image title diff --git a/pkg/obsolete/mkhistogram.par b/pkg/obsolete/mkhistogram.par new file mode 100644 index 00000000..8f250459 --- /dev/null +++ b/pkg/obsolete/mkhistogram.par @@ -0,0 +1,7 @@ +file,s,a,,,,File name +nbins,i,a,1,1,,Number of bins in histogram +z1,r,h,INDEF,,,Minimum histogram intensity +z2,r,h,INDEF,,,Maximum histogram intensity +listout,b,h,yes,,,List instead of plot histogram +device,s,h,"stdgraph",,,output graphics device +mode,s,h,ql,,, diff --git a/pkg/obsolete/mkpkg b/pkg/obsolete/mkpkg new file mode 100644 index 00000000..a321582e --- /dev/null +++ b/pkg/obsolete/mkpkg @@ -0,0 +1,41 @@ +# Make the OBSOLETE package. + +$call relink +$exit + +update: + $call relink + $call install + ; + +relink: + $update libpkg.a + $omake x_obsolete.x + $link x_obsolete.o libpkg.a -lxtools -o xx_obsolete.e + ; + +install: + $move xx_obsolete.e bin$x_obsolete.e + ; + +generic: + $set GEN = "$$generic -k" + + $ifolder (generic/fixcol.x, fixcol.gx) + $(GEN) fixcol.gx -o generic/fixcol.x $endif + $ifolder (generic/fixline.x, fixline.gx) + $(GEN) fixline.gx -o generic/fixline.x $endif + ; + +libpkg.a: + $ifeq (USE_GENERIC, yes) $call generic $endif + @generic + @fits + @imcombine + + t_fixpix.x <fset.h> <imhdr.h> + t_imtitle.x <imhdr.h> + t_mkhgm.x <gset.h> <mach.h> + t_oimstat.x <mach.h> <imhdr.h> "oimstat.h" + t_radplt.x <imhdr.h> <error.h> <mach.h> <gset.h> + ; diff --git a/pkg/obsolete/obsolete.cl b/pkg/obsolete/obsolete.cl new file mode 100644 index 00000000..26643d74 --- /dev/null +++ b/pkg/obsolete/obsolete.cl @@ -0,0 +1,14 @@ +#{ Package script task for the OBSOLETE package. + +package obsolete + +task imtitle, + mkhistogram, + ofixpix, + oimcombine, + oimstatistics, + orfits, + owfits, + radplt = obsolete$x_obsolete.e + +clbye diff --git a/pkg/obsolete/obsolete.hd b/pkg/obsolete/obsolete.hd new file mode 100644 index 00000000..58c60998 --- /dev/null +++ b/pkg/obsolete/obsolete.hd @@ -0,0 +1,15 @@ +# Help directory for the OBSOLETE package. + +$doc = "pkg$obsolete/doc/" +$fits = "pkg$obsolete/fits/" + +imtitle hlp =doc$imtitle.hlp, src = t_imtitle.x +mkhistogram hlp =doc$mkhistogram.hlp, src = t_mkhistogram.x +ofixpix hlp =doc$ofixpix.hlp, src = t_fixpix.x +oimcombine hlp =doc$oimcombine.hlp +oimstatistics hlp =doc$oimstat.hlp +orfits hlp =doc$orfits.hlp, src = fits$t_rfits.x +owfits hlp =doc$owfits.hlp, src = fits$t_wfits.x +radplt hlp =doc$radplt.hlp, src = t_radplt.x + +revisions sys=Revisions diff --git a/pkg/obsolete/obsolete.men b/pkg/obsolete/obsolete.men new file mode 100644 index 00000000..87b85715 --- /dev/null +++ b/pkg/obsolete/obsolete.men @@ -0,0 +1,11 @@ + imtitle - Change the title of an image (noao.proto V2.9) + mkhistogram - List or plot the histogram of a data stream (noao.proto V2.9) + ofixpix - Fix bad pixels using text file (proto V2.10.4) + oimcombine - IMCOMBINE from V2.11-V2.11.3 + oimstatistics - IMSTATISTICS from V2.11.3 + orfits - Convert a FITS image into an IRAF image (dataio V2.10.4) + owfits - Convert an IRAF image into a FITS image (dataio V2.10.4) + radplt - Plot the radial profile of an object (noao.proto V2.9) + + + The previous package and release is listed in parenthesis diff --git a/pkg/obsolete/obsolete.par b/pkg/obsolete/obsolete.par new file mode 100644 index 00000000..da669776 --- /dev/null +++ b/pkg/obsolete/obsolete.par @@ -0,0 +1,3 @@ +# OBSOLETE package parameter file. + +version,s,h,"September 2001" diff --git a/pkg/obsolete/ofixpix.par b/pkg/obsolete/ofixpix.par new file mode 100644 index 00000000..c15397c9 --- /dev/null +++ b/pkg/obsolete/ofixpix.par @@ -0,0 +1,5 @@ +# FIXPIX -- Replace bad pixels by linear interpolation + +images,s,a,,,,Images to be modified +badpixels,f,a,,,,Bad pixel regions file +verbose,b,h,no,,,Print the image name and bad regions? diff --git a/pkg/obsolete/oimcombine.par b/pkg/obsolete/oimcombine.par new file mode 100644 index 00000000..e1f6b3c1 --- /dev/null +++ b/pkg/obsolete/oimcombine.par @@ -0,0 +1,38 @@ +# IMCOMBINE -- Image combine parameters + +input,s,a,,,,List of images to combine +output,s,a,,,,List of output images +rejmask,s,h,"",,,List of rejection masks (optional) +plfile,s,h,"",,,List of pixel list files (optional) +sigma,s,h,"",,,List of sigma images (optional) +logfile,s,h,"STDOUT",,,"Log file +" +combine,s,h,"average","average|median",,Type of combine operation +reject,s,h,"none","none|minmax|ccdclip|crreject|sigclip|avsigclip|pclip",,Type of rejection +project,b,h,no,,,Project highest dimension of input images? +outtype,s,h,"real","short|ushort|integer|long|real|double",,Output image pixel datatype +offsets,f,h,"none",,,Input image offsets +masktype,s,h,"none","none|goodvalue|badvalue|goodbits|badbits",,Mask type +maskvalue,r,h,0,,,Mask value +blank,r,h,0.,,,"Value if there are no pixels +" +scale,s,h,"none",,,Image scaling +zero,s,h,"none",,,Image zero point offset +weight,s,h,"none",,,Image weights +statsec,s,h,"",,,Image section for computing statistics +expname,s,h,"",,,"Image header exposure time keyword +" +lthreshold,r,h,INDEF,,,Lower threshold +hthreshold,r,h,INDEF,,,Upper threshold +nlow,i,h,1,0,,minmax: Number of low pixels to reject +nhigh,i,h,1,0,,minmax: Number of high pixels to reject +nkeep,i,h,1,,,Minimum to keep (pos) or maximum to reject (neg) +mclip,b,h,yes,,,Use median in sigma clipping algorithms? +lsigma,r,h,3.,0.,,Lower sigma clipping factor +hsigma,r,h,3.,0.,,Upper sigma clipping factor +rdnoise,s,h,"0.",,,ccdclip: CCD readout noise (electrons) +gain,s,h,"1.",,,ccdclip: CCD gain (electrons/DN) +snoise,s,h,"0.",,,ccdclip: Sensitivity noise (fraction) +sigscale,r,h,0.1,0.,,Tolerance for sigma clipping scaling corrections +pclip,r,h,-0.5,,,pclip: Percentile clipping parameter +grow,r,h,0.,0.,,Radius (pixels) for neighbor rejection diff --git a/pkg/obsolete/oimstat.h b/pkg/obsolete/oimstat.h new file mode 100644 index 00000000..ba787642 --- /dev/null +++ b/pkg/obsolete/oimstat.h @@ -0,0 +1,50 @@ +# Header file for the IMSTATISTICS task. + +define LEN_IMSTAT 20 + +define IS_SUMX Memd[P2D($1)] +define IS_SUMX2 Memd[P2D($1+2)] +define IS_SUMX3 Memd[P2D($1+4)] +define IS_SUMX4 Memd[P2D($1+6)] +define IS_LO Memr[P2R($1+8)] +define IS_HI Memr[P2R($1+9)] +define IS_MIN Memr[P2R($1+10)] +define IS_MAX Memr[P2R($1+11)] +define IS_MEAN Memr[P2R($1+12)] +define IS_MEDIAN Memr[P2R($1+13)] +define IS_MODE Memr[P2R($1+14)] +define IS_STDDEV Memr[P2R($1+15)] +define IS_SKEW Memr[P2R($1+16)] +define IS_KURTOSIS Memr[P2R($1+17)] +define IS_NPIX Memi[$1+18] + +define IS_FIELDS "|image|npix|min|max|mean|midpt|mode|stddev|skew|kurtosis|" + +define NFIELDS 10 + +define IS_KIMAGE "IMAGE" +define IS_KNPIX "NPIX" +define IS_KMIN "MIN" +define IS_KMAX "MAX" +define IS_KMEAN "MEAN" +define IS_KMEDIAN "MIDPT" +define IS_KMODE "MODE" +define IS_KSTDDEV "STDDEV" +define IS_KSKEW "SKEW" +define IS_KKURTOSIS "KURTOSIS" + +define IS_FIMAGE 1 +define IS_FNPIX 2 +define IS_FMIN 3 +define IS_FMAX 4 +define IS_FMEAN 5 +define IS_FMEDIAN 6 +define IS_FMODE 7 +define IS_FSTDDEV 8 +define IS_FSKEW 9 +define IS_FKURTOSIS 10 + +define IS_FCOLUMN "%10d" +define IS_FINTEGER "%10d" +define IS_FREAL "%10.4g" +define IS_FSTRING "%20s" diff --git a/pkg/obsolete/oimstatistics.par b/pkg/obsolete/oimstatistics.par new file mode 100644 index 00000000..9bb004dc --- /dev/null +++ b/pkg/obsolete/oimstatistics.par @@ -0,0 +1,6 @@ +images,s,a,,,,Images +fields,s,h,"image,npix,mean,stddev,min,max",,,Fields to be printed +lower,r,h,INDEF,,,Lower cutoff for pixel values +upper,r,h,INDEF,,,Upper cutoff for pixel values +binwidth,r,h,0.1,,,Bin width of histogram in sigma +format,b,h,yes,,,Format output and print column labels? diff --git a/pkg/obsolete/orfits.par b/pkg/obsolete/orfits.par new file mode 100644 index 00000000..a5b1d704 --- /dev/null +++ b/pkg/obsolete/orfits.par @@ -0,0 +1,13 @@ +# FITS parameters +fits_file,f,a,mta,,,FITS data source +file_list,s,a,,,,File list +iraf_file,f,a,,,,IRAF filename +make_image,b,h,yes,,,Create an IRAF image? +long_header,b,h,no,,,Print FITS header cards? +short_header,b,h,yes,,,Print short header? +datatype,s,h,"",,,IRAF data type +blank,r,h,0.0,,,Blank value +scale,b,h,yes,,,Scale the data? +oldirafname,b,h,no,,,Use old IRAF name in place of iraf_file? +offset,i,h,0,,,Tape file offset +mode,s,h,ql,,, diff --git a/pkg/obsolete/owfits.par b/pkg/obsolete/owfits.par new file mode 100644 index 00000000..e89d1a58 --- /dev/null +++ b/pkg/obsolete/owfits.par @@ -0,0 +1,14 @@ +# FITS parameters +iraf_files,s,a,,,,IRAF images +fits_files,f,a,,,,FITS filename +newtape,b,a,,,,Blank tape? +make_image,b,h,yes,,,Create a FITS image? +long_header,b,h,no,,,Print FITS header cards? +short_header,b,h,yes,,,Print short header? +bitpix,i,h,0,,,FITS bits per pixel +blocking_factor,i,h,0,0,10,FITS tape blocking factor +scale,b,h,yes,,,Scale data? +autoscale,b,h,yes,,,Auto_scaling? +bscale,r,a,1.0,,,FITS bscale +bzero,r,a,0.0,,,FITS bzero +mode,s,h,ql,,, diff --git a/pkg/obsolete/radplt.par b/pkg/obsolete/radplt.par new file mode 100644 index 00000000..cd296b1f --- /dev/null +++ b/pkg/obsolete/radplt.par @@ -0,0 +1,5 @@ +input,s,a,,,,Image names +x_init,r,a,,,,Approx x position of star +y_init,r,a,,,,Approx y position of star +cboxsize,i,h,5,3,,Size of extraction box +rboxsize,i,h,21,3,,Size of profile extraction box diff --git a/pkg/obsolete/t_fixpix.x b/pkg/obsolete/t_fixpix.x new file mode 100644 index 00000000..4442cd32 --- /dev/null +++ b/pkg/obsolete/t_fixpix.x @@ -0,0 +1,172 @@ +include <imhdr.h> +include <fset.h> + +# FIXPIX -- Interpolate over bad columns and lines. + +procedure t_fixpix () + +char images[SZ_LINE] # Image template +char badpixels[SZ_FNAME] # File containing the badpixel regions +bool verbose # Print image names and regions? + +char imname[SZ_FNAME] # Image name +pointer image # Image pointer + +int list, badpix + +int open(), imtopen(), imtgetim() +bool clgetb() +pointer immap() + +begin + # Get the image template and expand. + + call clgstr ("images", images, SZ_LINE) + call clgstr ("badpixels", badpixels, SZ_FNAME) + verbose = clgetb ("verbose") + if (verbose) + call fseti (STDOUT, F_FLUSHNL, YES) + + list = imtopen (images) + + while (imtgetim (list, imname, SZ_FNAME) != EOF) { + + if (verbose) { + call printf ("fixpix: %s\n") + call pargstr (imname) + } + image = immap (imname, READ_WRITE, 0) + badpix = open (badpixels, READ_ONLY, TEXT_FILE) + call fixpix (image, badpix, verbose) + call imunmap (image) + call close (badpix) + } + + call imtclose (list) +end + +procedure fixpix (image, badpix, verbose) + +pointer image # Image pointer +int badpix # File pointer +bool verbose # Print regions fixed? + +int x1, x2, y1, y2 # Bad region + +int temp, fscan(), nscan() + +begin + # Scan the bad pixel regions from the file. + + while (fscan (badpix) != EOF) { + call gargi (x1) + call gargi (x2) + call gargi (y1) + call gargi (y2) + if (nscan () != 4) + next + + if (x1 > x2) { + temp = x1; x1 = x2; x2 = temp + } + if (y1 > y2) { + temp = y1; y1 = y2; y2 = temp + } + + # Check that the region is not the entire image. + + if ((x1 == 1) && (x2 == IM_LEN (image, 1)) && + (y1 == 1) && (y2 == IM_LEN (image, 2))) { + call eprintf ("Cannot fix an entire image") + next + } + + # If the bad region spans entire lines interpolate lines. + if ((x1 == 1) && (x2 == IM_LEN (image, 1))) + call fixline (image, x1, x2, y1, y2, verbose) + + # If the bad region spans entire columns interpolate columns. + else if ((y1 == 1) && (y2 == IM_LEN (image, 2))) + call fixcolumn (image, x1, x2, y1, y2, verbose) + + # If the bad region is longer in the columns interpolate columns. + else if ((x2 - x1) < (y2 - y1)) + call fixcolumn (image, x1, x2, y1, y2, verbose) + + # If the bad region is longer in the lines interpolate lines. + else + call fixline (image, x1, x2, y1, y2, verbose) + } +end + +# FIXLINE -- Switch to the appropriate generic procedure to optimize the +# image I/O. + +procedure fixline (image, x1, x2, y1, y2, verbose) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed +bool verbose # Print regions fixed? + +begin + if (verbose) { + call printf (" Interpolate lines for region %d %d %d %d\n") + call pargi (x1) + call pargi (x2) + call pargi (y1) + call pargi (y2) + } + + switch (IM_PIXTYPE (image)) { + case TY_SHORT: + call fixlines (image, x1, x2, y1, y2) + case TY_INT: + call fixlinei (image, x1, x2, y1, y2) + case TY_USHORT, TY_LONG: + call fixlinel (image, x1, x2, y1, y2) + case TY_REAL: + call fixliner (image, x1, x2, y1, y2) + case TY_DOUBLE: + call fixlined (image, x1, x2, y1, y2) + case TY_COMPLEX: + call fixlinex (image, x1, x2, y1, y2) + default: + call eprintf ("Unknown pixel type") + } +end + +# FIXCOLUMN -- Switch to the appropriate generic procedure to optimize the +# image I/O. + +procedure fixcolumn (image, x1, x2, y1, y2, verbose) + +pointer image # Image pointer +int x1, x2, y1, y2 # Region to be fixed +bool verbose # Print regions fixed? + +begin + if (verbose) { + call printf (" Interpolate columns for region %d %d %d %d\n") + call pargi (x1) + call pargi (x2) + call pargi (y1) + call pargi (y2) + } + + switch (IM_PIXTYPE (image)) { + case TY_SHORT: + call fixcols (image, x1, x2, y1, y2) + case TY_INT: + call fixcoli (image, x1, x2, y1, y2) + case TY_USHORT, TY_LONG: + call fixcoll (image, x1, x2, y1, y2) + case TY_REAL: + call fixcolr (image, x1, x2, y1, y2) + case TY_DOUBLE: + call fixcold (image, x1, x2, y1, y2) + case TY_COMPLEX: + call fixcolx (image, x1, x2, y1, y2) + default: + call eprintf ("Unknown pixel type") + } +end diff --git a/pkg/obsolete/t_imtitle.x b/pkg/obsolete/t_imtitle.x new file mode 100644 index 00000000..d4edeb35 --- /dev/null +++ b/pkg/obsolete/t_imtitle.x @@ -0,0 +1,21 @@ +include <imhdr.h> + +# T_IMTITLE -- Set the title of an image. + +procedure t_imtitle () + +char image[SZ_FNAME] # Image to be editted + +pointer im, immap() + +begin + # Access image. + call clgstr ("image", image, SZ_FNAME) + im = immap (image, READ_WRITE, 0) + + # Substitute new title. + call clgstr ("title", IM_TITLE(im), SZ_IMTITLE) + + # Unmap image. + call imunmap (im) +end diff --git a/pkg/obsolete/t_mkhgm.x b/pkg/obsolete/t_mkhgm.x new file mode 100644 index 00000000..6bc906dc --- /dev/null +++ b/pkg/obsolete/t_mkhgm.x @@ -0,0 +1,137 @@ +include <mach.h> +include <gset.h> + +define SZ_HISTBUF 512 + +# HISTOGRAM -- Compute and plot the histogram of an file. + +procedure t_mkhistogram() + +bool listout +int fd, ndata, nbins +pointer sp, file, device, data, hgm, hgmr, gp +real z1, z2, zmin, zmax, dz, zval + +bool clgetb(), fp_equalr() +int i, clgeti(), open(), get_histdata() +real clgetr() +pointer gopen() + +begin + call smark (sp) + call salloc (file, SZ_LINE, TY_CHAR) + call salloc (device, SZ_FNAME, TY_CHAR) + + # Get the file name. + call clgstr ("file", Memc[file], SZ_LINE) + fd = open (Memc[file], READ_ONLY, TEXT_FILE) + + # Output can be either a list or a plot. + listout = clgetb ("listout") + if (! listout) + call clgstr ("device", Memc[device], SZ_FNAME) + + + # Get histogram length and allocate buffer. + nbins = clgeti ("nbins") + if (nbins < 2) { + call eprintf ("Warning: Less than 2 bins in histogram.\n") + call sfree (sp) + return + } + call salloc (hgm, nbins, TY_INT) + call salloc (hgmr, nbins, TY_REAL) + + # Fetch the data. + call malloc (data, SZ_HISTBUF, TY_REAL) + ndata = get_histdata (fd, data, SZ_HISTBUF) + if (ndata <= 0) { + call eprintf ("Warning: No input data for histogram.\n") + call mfree (data, TY_REAL) + call sfree (sp) + return + } + + z1 = clgetr ("z1") + z2 = clgetr ("z2") + if (IS_INDEFR(z1) || IS_INDEFR(z2)) { + call alimr (Memr[data], ndata, zmin, zmax) + if (IS_INDEFR(z1)) + z1 = zmin + if (IS_INDEFR(z2)) + z2 = zmax + } + dz = (z2 - z1) / (nbins - 1) + + # Test for constant valued file, which causes zero divide in ahgm. + if (fp_equalr (z1, z2)) { + call eprintf ( + "Warning: Constant valued file `%s' has no data range.\n") + call pargstr (Memc[file]) + call mfree (data, TY_REAL) + call sfree (sp) + return + } + + # Initialize histogram and file line vector. + call aclri (Memi[hgm], nbins) + + # Accumulate the histogram. + call ahgmr (Memr[data], ndata, Memi[hgm], nbins, z1, z2) + + # List or plot the histogram. + if (listout) { + zval = z1 + do i = 1, nbins { + call printf ("%4d %g %d\n") + call pargi (i) + call pargr (zval + dz / 2.) + call pargi (Memi[hgm+i-1]) + zval = zval + dz + } + } else { + gp = gopen (Memc[device], NEW_FILE, STDGRAPH) + #call gseti (gp, G_YTRAN, GW_LOG) + call achtir (Memi[hgm], Memr[hgmr], nbins) + call gploto (gp, Memr[hgmr], nbins, z1 + dz / 2., z2 + dz / 2., + Memc[file]) + call gclose (gp) + } + + # Shutdown. + call close (fd) + call sfree (sp) +end + + +# GET_HISTDATA -- Procedure to get data for the histogram + +int procedure get_histdata (fd, data, buf_incr) + +int fd # file descriptor of histogram data +pointer data # pointer to the data array +int buf_incr # increment for data buffer size + +int szbuf, ndata +int fscan(), nscan() + +begin + szbuf = buf_incr + ndata = 0 + while (fscan (fd) != EOF) { + call gargr (Memr[data+ndata]) + if (nscan() != 1) + next + ndata = ndata + 1 + if (ndata == szbuf) { + szbuf = szbuf + buf_incr + call realloc (data, szbuf, TY_REAL) + } + } + + # Fit the buffer size to the data. + if (ndata > 0) + call realloc (data, ndata, TY_REAL) + + return (ndata) +end diff --git a/pkg/obsolete/t_oimstat.x b/pkg/obsolete/t_oimstat.x new file mode 100644 index 00000000..417d1eed --- /dev/null +++ b/pkg/obsolete/t_oimstat.x @@ -0,0 +1,1014 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <imhdr.h> +include "oimstat.h" + + +# T_OIMSTATISTICS -- Compute and print the statistics of images. + +procedure t_oimstatistics () + +pointer fieldstr # Pointer to fields string +real lower # Lower limit of data value window +real upper # Upper limit of data value window +real binwidth # Width of histogram bin in sigma +int format # Format the output + +int nfields, nbins +int minmax, npix, mean, median, mode, stddev, skew, kurtosis +pointer sp, fields, image, v +pointer im, list, ist, buf, hgm +real hwidth, hmin, hmax + +bool clgetb() +int ist_fields(), ist_isfield, imtgetim(), ist_ihist(), btoi() +pointer imtopenp(), imgnlr() +real clgetr() +pointer immap() + +begin + call smark (sp) + call salloc (fieldstr, SZ_LINE, TY_CHAR) + call salloc (fields, NFIELDS, TY_INT) + call salloc (ist, LEN_IMSTAT, TY_STRUCT) + call salloc (image, SZ_FNAME, TY_CHAR) + call salloc (v, IM_MAXDIM, TY_LONG) + + # Open the list of input images, the fields and the data value limits. + list = imtopenp ("images") + call clgstr ("fields", Memc[fieldstr], SZ_LINE) + lower = clgetr ("lower") + upper = clgetr ("upper") + binwidth = clgetr ("binwidth") + format = btoi (clgetb ("format")) + + # Get the selected fields. + nfields = ist_fields (Memc[fieldstr], Memi[fields], NFIELDS) + if (nfields <= 0) { + call imtclose (list) + call sfree (sp) + return + } + + # Set the computation switches. + npix = ist_isfield (IS_FNPIX, Memi[fields], nfields) + mean = ist_isfield (IS_FMEAN, Memi[fields], nfields) + median = ist_isfield (IS_FMEDIAN, Memi[fields], nfields) + mode = ist_isfield (IS_FMODE, Memi[fields], nfields) + stddev = ist_isfield (IS_FSTDDEV, Memi[fields], nfields) + skew = ist_isfield (IS_FSKEW, Memi[fields], nfields) + kurtosis = ist_isfield (IS_FKURTOSIS, Memi[fields], nfields) + if (ist_isfield (IS_FMIN, Memi[fields], nfields) == YES) + minmax = YES + else if (ist_isfield (IS_FMAX, Memi[fields], nfields) == YES) + minmax = YES + else if (median == YES || mode == YES) + minmax = YES + else + minmax = NO + + # Print a header banner for the selected fields. + if (format == YES) + call ist_pheader (Memi[fields], nfields) + + # Loop through the input images. + while (imtgetim (list, Memc[image], SZ_FNAME) != EOF) { + + im = immap (Memc[image], READ_ONLY, 0) + call ist_initialize (ist, lower, upper) + + # Accumulate the central moment statistics. + call amovkl (long(1), Meml[v], IM_MAXDIM) + if (kurtosis == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate4 (ist, Memr[buf], int (IM_LEN(im, 1)), + lower, upper, minmax) + } else if (skew == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate3 (ist, Memr[buf], int (IM_LEN (im, 1)), + lower, upper, minmax) + } else if (stddev == YES || median == YES || mode == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate2 (ist, Memr[buf], int (IM_LEN(im,1)), + lower, upper, minmax) + } else if (mean == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate1 (ist, Memr[buf], int (IM_LEN(im,1)), + lower, upper, minmax) + } else if (npix == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate0 (ist, Memr[buf], int (IM_LEN(im,1)), + lower, upper, minmax) + } else if (minmax == YES) { + while (imgnlr (im, buf, Meml[v]) != EOF) + call ist_accumulate0 (ist, Memr[buf], int (IM_LEN(im,1)), + lower, upper, YES) + } + + # Compute the central moment statistics. + call ist_stats (ist, skew, kurtosis) + + # Accumulate the histogram. + hgm = NULL + if ((median == YES || mode == YES) && ist_ihist (ist, binwidth, + hgm, nbins, hwidth, hmin, hmax) == YES) { + call aclri (Memi[hgm], nbins) + call amovkl (long(1), Meml[v], IM_MAXDIM) + while (imgnlr (im, buf, Meml[v]) != EOF) + call ahgmr (Memr[buf], int(IM_LEN(im,1)), Memi[hgm], nbins, + hmin, hmax) + if (median == YES) + call ist_hmedian (ist, Memi[hgm], nbins, hwidth, hmin, + hmax) + if (mode == YES) + call ist_hmode (ist, Memi[hgm], nbins, hwidth, hmin, hmax) + } + + # Print the statistics. + if (format == YES) + call ist_print (Memc[image], ist, Memi[fields], nfields) + else + call ist_fprint (Memc[image], ist, Memi[fields], nfields) + + if (hgm != NULL) + call mfree (hgm, TY_INT) + call imunmap (im) + } + + call imtclose (list) + call sfree (sp) +end + + +# IST_FIELDS -- Procedure to decode the fields string into a list of the +# fields to be computed and printed. + +int procedure ist_fields (fieldstr, fields, max_nfields) + +char fieldstr[ARB] # string containing the list of fields +int fields[ARB] # fields array +int max_nfields # maximum number of fields + +int nfields, flist, field +pointer sp, fname +int fntopnb(), fntgfnb(), strdic() + +begin + nfields = 0 + + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + + flist = fntopnb (fieldstr, NO) + while (fntgfnb (flist, Memc[fname], SZ_FNAME) != EOF && + (nfields < max_nfields)) { + field = strdic (Memc[fname], Memc[fname], SZ_FNAME, IS_FIELDS) + if (field == 0) + next + nfields = nfields + 1 + fields[nfields] = field + } + call fntclsb (flist) + + call sfree (sp) + + return (nfields) +end + + +# IST_ISFIELD -- Procedure to determine whether a specified field is one +# of the selected fields or not. + +int procedure ist_isfield (field, fields, nfields) + +int field # field to be tested +int fields[ARB] # array of selected fields +int nfields # number of fields + +int i, isfield + +begin + isfield = NO + do i = 1, nfields { + if (field != fields[i]) + next + isfield = YES + break + } + + return (isfield) +end + + +# IST_INITIALIZE -- Initialize the sum array to zero. + +procedure ist_initialize (ist, lower, upper) + +pointer ist # pointer to the statistics structure +real lower # lower datalimit +real upper # upperlimit + +begin + if (IS_INDEFR(lower)) + IS_LO(ist) = -MAX_REAL + else + IS_LO(ist) = lower + if (IS_INDEFR(upper)) + IS_HI(ist) = MAX_REAL + else + IS_HI(ist) = upper + + IS_NPIX(ist) = 0 + IS_SUMX(ist) = 0.0d0 + IS_SUMX2(ist) = 0.0d0 + IS_SUMX3(ist) = 0.0d0 + IS_SUMX4(ist) = 0.0d0 + + IS_MIN(ist) = MAX_REAL + IS_MAX(ist) = -MAX_REAL + IS_MEAN(ist) = INDEFR + IS_MEDIAN(ist) = INDEFR + IS_MODE(ist) = INDEFR + IS_STDDEV(ist) = INDEFR + IS_SKEW(ist) = INDEFR + IS_KURTOSIS(ist) = INDEFR +end + + +# IST_ACCUMULATE4 -- Accumulate sums up to the fourth power of the data for +# data values between lower and upper. + +procedure ist_accumulate4 (is, x, npts, lower, upper, minmax) + +pointer is # pointer to the statistics structure +real x[ARB] # the data array +int npts # the number of data points +real lower # lower data boundary +real upper # upper data boundary +int minmax # compute the minimum and maximum + +int i, npix +real lo, hi, xmin, xmax +double xx, xx2, sumx, sumx2, sumx3, sumx4 + +begin + lo = IS_LO(is) + hi = IS_HI(is) + npix = IS_NPIX(is) + sumx = 0.0 + sumx2 = 0.0 + sumx3 = 0.0 + sumx4 = 0.0 + xmin = IS_MIN(is) + xmax = IS_MAX(is) + + if (IS_INDEFR(lower) && IS_INDEFR(upper)) { + npix = npix + npts + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + sumx4 = sumx4 + xx2 * xx2 + } + } else { + do i = 1, npts { + xx = x[i] + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + sumx4 = sumx4 + xx2 * xx2 + } + } + } else { + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + npix = npix + 1 + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + sumx4 = sumx4 + xx2 * xx2 + } + } else { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + sumx4 = sumx4 + xx2 * xx2 + } + } + } + + IS_NPIX(is) = npix + IS_SUMX(is) = IS_SUMX(is) + sumx + IS_SUMX2(is) = IS_SUMX2(is) + sumx2 + IS_SUMX3(is) = IS_SUMX3(is) + sumx3 + IS_SUMX4(is) = IS_SUMX4(is) + sumx4 + IS_MIN(is) = xmin + IS_MAX(is) = xmax +end + + +# IST_ACCUMULATE3 -- Accumulate sums up to the third power of the data for +# data values between lower and upper. + +procedure ist_accumulate3 (is, x, npts, lower, upper, minmax) + +pointer is # pointer to the statistics structure +real x[ARB] # the data array +int npts # the number of data points +real lower # lower data boundary +real upper # upper data boundary +int minmax # compute the minimum and maximum + +int i, npix +real lo, hi, xmin, xmax +double xx, xx2, sumx, sumx2, sumx3 + +begin + lo = IS_LO(is) + hi = IS_HI(is) + npix = IS_NPIX(is) + sumx = 0.0 + sumx2 = 0.0 + sumx3 = 0.0 + xmin = IS_MIN(is) + xmax = IS_MAX(is) + + if (IS_INDEFR(lower) && IS_INDEFR(upper)) { + npix = npix + npts + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + } + } else { + do i = 1, npts { + xx = x[i] + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + } + } + } else { + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + npix = npix + 1 + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + } + } else { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + xx2 = xx * xx + sumx = sumx + xx + sumx2 = sumx2 + xx2 + sumx3 = sumx3 + xx2 * xx + } + } + } + + IS_NPIX(is) = npix + IS_SUMX(is) = IS_SUMX(is) + sumx + IS_SUMX2(is) = IS_SUMX2(is) + sumx2 + IS_SUMX3(is) = IS_SUMX3(is) + sumx3 + IS_MIN(is) = xmin + IS_MAX(is) = xmax +end + + +# IST_ACCUMULATE2 -- Accumulate sums up to the second power of the data for +# data values between lower and upper. + +procedure ist_accumulate2 (is, x, npts, lower, upper, minmax) + +pointer is # pointer to the statistics structure +real x[ARB] # the data array +int npts # the number of data points +real lower # lower data boundary +real upper # upper data boundary +int minmax # compute the minimum and maximum + +int i, npix +real lo, hi, xmin, xmax +double xx, sumx, sumx2 + +begin + lo = IS_LO(is) + hi = IS_HI(is) + npix = IS_NPIX(is) + sumx = 0.0 + sumx2 = 0.0 + xmin = IS_MIN(is) + xmax = IS_MAX(is) + + if (IS_INDEFR(lower) && IS_INDEFR(upper)) { + npix = npix + npts + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + sumx = sumx + xx + sumx2 = sumx2 + xx * xx + } + } else { + do i = 1, npts { + xx = x[i] + sumx = sumx + xx + sumx2 = sumx2 + xx * xx + } + } + } else { + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + npix = npix + 1 + sumx = sumx + xx + sumx2 = sumx2 + xx * xx + } + } else { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + sumx = sumx + xx + sumx2 = sumx2 + xx * xx + } + } + } + + IS_NPIX(is) = npix + IS_SUMX(is) = IS_SUMX(is) + sumx + IS_SUMX2(is) = IS_SUMX2(is) + sumx2 + IS_MIN(is) = xmin + IS_MAX(is) = xmax +end + + +# IST_ACCUMULATE1 -- Accumulate sums up to the first power of the data for +# data values between lower and upper. + +procedure ist_accumulate1 (is, x, npts, lower, upper, minmax) + +pointer is # pointer to the statistics structure +real x[ARB] # the data array +int npts # the number of data points +real lower # lower data boundary +real upper # upper data boundary +int minmax # compute the minimum and maximum + +int i, npix +real lo, hi, xx, xmin, xmax +double sumx + +begin + lo = IS_LO(is) + hi = IS_HI(is) + npix = IS_NPIX(is) + sumx = 0.0 + xmin = IS_MIN(is) + xmax = IS_MAX(is) + + if (IS_INDEFR(lower) && IS_INDEFR(upper)) { + npix = npix + npts + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + sumx = sumx + xx + } + } else { + do i = 1, npts + sumx = sumx + x[i] + } + } else { + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + sumx = sumx + xx + } + } else { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + sumx = sumx + xx + } + } + } + + IS_NPIX(is) = npix + IS_SUMX(is) = IS_SUMX(is) + sumx + IS_MIN(is) = xmin + IS_MAX(is) = xmax +end + + +# IST_ACCUMULATE0 -- Accumulate sums up to the 0th power of the data for +# data values between lower and upper. + +procedure ist_accumulate0 (is, x, npts, lower, upper, minmax) + +pointer is # pointer to the statistics structure +real x[ARB] # the data array +int npts # the number of data points +real lower # lower data boundary +real upper # upper data boundary +int minmax # compute the minimum and maximum + +int i, npix +real lo, hi, xx, xmin, xmax + +begin + lo = IS_LO(is) + hi = IS_HI(is) + npix = IS_NPIX(is) + xmin = IS_MIN(is) + xmax = IS_MAX(is) + + if (IS_INDEFR(lower) && IS_INDEFR(upper)) { + npix = npix + npts + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + } + } + } else { + if (minmax == YES) { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + if (xx < xmin) + xmin = xx + if (xx > xmax) + xmax = xx + } + } else { + do i = 1, npts { + xx = x[i] + if (xx < lo || xx > hi) + next + npix = npix + 1 + } + } + } + + IS_NPIX(is) = npix + IS_MIN(is) = xmin + IS_MAX(is) = xmax +end + + +# IST_STATS -- Procedure to compute the first four central moments of the +# distribution. + +procedure ist_stats (ist, bskew, bkurtosis) + +pointer ist # statistics structure +int bskew # skew switch +int bkurtosis # kurtosis switch + +double mean, var, stdev +bool fp_equalr() + +begin + if (fp_equalr (IS_MIN(ist), MAX_REAL)) + IS_MIN(ist) = INDEFR + if (fp_equalr (IS_MAX(ist), -MAX_REAL)) + IS_MAX(ist) = INDEFR + + if (IS_NPIX(ist) <= 0) + return + mean = IS_SUMX(ist) / IS_NPIX(ist) + IS_MEAN(ist) = mean + + if (IS_NPIX(ist) < 2) + return + var = (IS_SUMX2(ist) - IS_SUMX(ist) * mean) / + (IS_NPIX(ist) - 1) + if (var <= 0.0) { + IS_STDDEV(ist) = 0.0 + return + } else { + stdev = sqrt (var) + IS_STDDEV(ist) = stdev + } + + if (bskew == YES) + IS_SKEW(ist) = (IS_SUMX3(ist) - 3.0d0 * IS_MEAN(ist) * + IS_SUMX2(ist) + 3.0d0 * mean * mean * + IS_SUMX(ist) - IS_NPIX(ist) * mean ** 3) / + IS_NPIX(ist) / stdev / stdev / stdev + + if (bkurtosis == YES) + IS_KURTOSIS(ist) = (IS_SUMX4(ist) - 4.0d0 * mean * + IS_SUMX3(ist) + 6.0d0 * mean * mean * + IS_SUMX2(ist) - 4.0 * mean ** 3 * IS_SUMX(ist) + + IS_NPIX(ist) * mean ** 4) / IS_NPIX(ist) / + stdev / stdev / stdev / stdev - 3.0d0 +end + + +# IST_IHIST -- Procedure to initilaize the histogram of the image pixels. + +int procedure ist_ihist (ist, binwidth, hgm, nbins, hwidth, hmin, hmax) + +pointer ist # pointer to the statistics structure +real binwidth # histogram bin width in sigma +pointer hgm # pointer to the histogram +int nbins # number of bins +real hwidth # histogram resolution +real hmin # minimum histogram value +real hmax # maximum histogram value + +begin + nbins = 0 + if (binwidth <= 0.0) + return (NO) + hwidth = binwidth * IS_STDDEV(ist) + if (hwidth <= 0.0) + return (NO) + nbins = (IS_MAX(ist) - IS_MIN(ist)) / hwidth + 1 + if (nbins < 3) + return (NO) + + hmin = IS_MIN(ist) + hmax = IS_MAX(ist) + call malloc (hgm, nbins, TY_INT) + return (YES) +end + + +# IST_HMEDIAN -- Procedure to compute the median of the values. + +procedure ist_hmedian (ist, hgm, nbins, hwidth, hmin, hmax) + +pointer ist # pointer to the statistics strucuture +int hgm[ARB] # histogram of the pixels +int nbins # number of bins in the histogram +real hwidth # resolution of the histogram +real hmin # minimum histogram value +real hmax # maximum histogram value + +int i, lo, hi +pointer sp, ihgm +real h1, hdiff, hnorm +bool fp_equalr() + +begin + call smark (sp) + call salloc (ihgm, nbins, TY_REAL) + + # Integrate the histogram and normalize. + Memr[ihgm] = hgm[1] + do i = 2, nbins + Memr[ihgm+i-1] = hgm[i] + Memr[ihgm+i-2] + hnorm = Memr[ihgm+nbins-1] + call adivkr (Memr[ihgm], hnorm, Memr[ihgm], nbins) + + # Initialize the low and high bin numbers. + lo = 0 + hi = 1 + + # Search for the point which divides the integral in half. + do i = 1, nbins { + if (Memr[ihgm+i-1] > 0.5) + break + lo = i + } + hi = lo + 1 + #call eprintf ( + #"hmin=%g hmax=%g hw=%g nbins=%d lo=%d ih(lo)=%g hi=%d ih(hi)=%g\n") + #call pargr (hmin) + #call pargr (hmax) + #call pargr (hwidth) + #call pargi (nbins) + #call pargi (lo) + #call pargr (Memr[ihgm+lo-1]) + #call pargi (hi) + #call pargr (Memr[ihgm+hi-1]) + + # Approximate the histogram. + h1 = hmin + lo * hwidth + if (lo == 0) + hdiff = Memr[ihgm+hi-1] + else + hdiff = Memr[ihgm+hi-1] - Memr[ihgm+lo-1] + if (fp_equalr (hdiff, 0.0)) + IS_MEDIAN(ist) = h1 + else if (lo == 0) + IS_MEDIAN(ist) = h1 + 0.5 / hdiff * hwidth + else + IS_MEDIAN(ist) = h1 + (0.5 - Memr[ihgm+lo-1]) / hdiff * hwidth + #call eprintf ("hlo=%g hhi=%g h1=%g hdiff=%g median=%g\n") + #call pargr (hmin) + #call pargr (hmin + (nbins - 1) * hwidth) + #call pargr (h1) + #call pargr (hdiff) + #call pargr (IS_MEDIAN(ist)) + + call sfree (sp) +end + + +# IST_HMODE -- Procedure to compute the mode. + +procedure ist_hmode (ist, hgm, nbins, hwidth, hmin, hmax) + +pointer ist # pointer to the statistics strucuture +int hgm[ARB] # histogram of the pixels +int nbins # number of bins in the histogram +real hwidth # resolution of the histogram +real hmin # minimum histogram value +real hmax # maximum histogram value + +int i, bpeak +real hpeak, dh1, dh2, denom +bool fp_equalr() + +begin + # If there is a single bin return the midpoint of that bin. + if (nbins == 1) { + IS_MODE(ist) = hmin + 0.5 * hwidth + return + } + + # If there are two bins return the midpoint of the greater bin. + if (nbins == 2) { + if (hgm[1] > hgm[2]) + IS_MODE(ist) = hmin + 0.5 * hwidth + else if (hgm[2] > hgm[1]) + IS_MODE(ist) = hmin + 1.5 * hwidth + else + IS_MODE(ist) = hmin + hwidth + return + } + + # Find the bin containing the histogram maximum. + hpeak = hgm[1] + bpeak = 1 + do i = 2, nbins { + if (hgm[i] > hpeak) { + hpeak = hgm[i] + bpeak = i + } + } + + # If the maximum is in the first bin return the midpoint of the bin. + if (bpeak == 1) { + IS_MODE(ist) = hmin + 0.5 * hwidth + return + } + + # If the maximum is in the last bin return the midpoint of the bin. + if (bpeak == nbins) { + IS_MODE(ist) = hmin + (nbins - 0.5) * hwidth + return + } + + # Compute the lower limit of bpeak. + bpeak = bpeak - 1 + + # Do a parabolic interpolation to find the peak. + dh1 = hgm[bpeak+1] - hgm[bpeak] + dh2 = hgm[bpeak+1] - hgm[bpeak+2] + denom = dh1 + dh2 + if (fp_equalr (denom, 0.0)) { + IS_MODE(ist) = hmin + (bpeak + 0.5) * hwidth + } else { + IS_MODE(ist) = bpeak + 1 + 0.5 * (dh1 - dh2) / denom + IS_MODE(ist) = hmin + (IS_MODE(ist) - 0.5) * hwidth + } + + + dh1 = hgm[bpeak] * (hmin + (bpeak - 0.5) * hwidth) + + hgm[bpeak+1] * (hmin + (bpeak + 0.5) * hwidth) + + hgm[bpeak+2] * (hmin + (bpeak + 1.5) * hwidth) + dh2 = hgm[bpeak] + hgm[bpeak+1] + hgm[bpeak+2] +end + + +# IST_PHEADER -- Print the banner fields. + +procedure ist_pheader (fields, nfields) + +int fields[ARB] # fields to be printed +int nfields # number of fields + +int i + +begin + call printf ("#") + do i = 1, nfields { + switch (fields[i]) { + case IS_FIMAGE: + call printf (IS_FSTRING) + call pargstr (IS_KIMAGE) + case IS_FNPIX: + call printf (IS_FCOLUMN) + call pargstr (IS_KNPIX) + case IS_FMIN: + call printf (IS_FCOLUMN) + call pargstr (IS_KMIN) + case IS_FMAX: + call printf (IS_FCOLUMN) + call pargstr (IS_KMAX) + case IS_FMEAN: + call printf (IS_FCOLUMN) + call pargstr (IS_KMEAN) + case IS_FMEDIAN: + call printf (IS_FCOLUMN) + call pargstr (IS_KMEDIAN) + case IS_FMODE: + call printf (IS_FCOLUMN) + call pargstr (IS_KMODE) + case IS_FSTDDEV: + call printf (IS_FCOLUMN) + call pargstr (IS_KSTDDEV) + case IS_FSKEW: + call printf (IS_FCOLUMN) + call pargstr (IS_KSKEW) + case IS_FKURTOSIS: + call printf (IS_FCOLUMN) + call pargstr (IS_KKURTOSIS) + } + } + + call printf ("\n") + call flush (STDOUT) +end + + +# IST_PRINT -- Print the fields + +procedure ist_print (image, ist, fields, nfields) + +char image[ARB] # image name +pointer ist # pointer to the statistics structure +int fields[ARB] # fields to be printed +int nfields # number of fields + +int i + +begin + call printf (" ") + do i = 1, nfields { + switch (fields[i]) { + case IS_FIMAGE: + call printf (IS_FSTRING) + call pargstr (image) + case IS_FNPIX: + call printf (IS_FINTEGER) + call pargi (IS_NPIX(ist)) + case IS_FMIN: + call printf (IS_FREAL) + call pargr (IS_MIN(ist)) + case IS_FMAX: + call printf (IS_FREAL) + call pargr (IS_MAX(ist)) + case IS_FMEAN: + call printf (IS_FREAL) + call pargr (IS_MEAN(ist)) + case IS_FMEDIAN: + call printf (IS_FREAL) + call pargr (IS_MEDIAN(ist)) + case IS_FMODE: + call printf (IS_FREAL) + call pargr (IS_MODE(ist)) + case IS_FSTDDEV: + call printf (IS_FREAL) + call pargr (IS_STDDEV(ist)) + case IS_FSKEW: + call printf (IS_FREAL) + call pargr (IS_SKEW(ist)) + case IS_FKURTOSIS: + call printf (IS_FREAL) + call pargr (IS_KURTOSIS(ist)) + } + } + + call printf ("\n") + call flush (STDOUT) +end + + +# IST_FPRINT -- Print the fields using a free format. + +procedure ist_fprint (image, ist, fields, nfields) + +char image[ARB] # image name +pointer ist # pointer to the statistics structure +int fields[ARB] # fields to be printed +int nfields # number of fields + +int i + +begin + do i = 1, nfields { + switch (fields[i]) { + case IS_FIMAGE: + call printf ("%s") + call pargstr (image) + case IS_FNPIX: + call printf ("%d") + call pargi (IS_NPIX(ist)) + case IS_FMIN: + call printf ("%g") + call pargr (IS_MIN(ist)) + case IS_FMAX: + call printf ("%g") + call pargr (IS_MAX(ist)) + case IS_FMEAN: + call printf ("%g") + call pargr (IS_MEAN(ist)) + case IS_FMEDIAN: + call printf ("%g") + call pargr (IS_MEDIAN(ist)) + case IS_FMODE: + call printf ("%g") + call pargr (IS_MODE(ist)) + case IS_FSTDDEV: + call printf ("%g") + call pargr (IS_STDDEV(ist)) + case IS_FSKEW: + call printf ("%g") + call pargr (IS_SKEW(ist)) + case IS_FKURTOSIS: + call printf ("%g") + call pargr (IS_KURTOSIS(ist)) + } + if (i < nfields) + call printf (" ") + } + + call printf ("\n") + call flush (STDOUT) +end diff --git a/pkg/obsolete/t_radplt.x b/pkg/obsolete/t_radplt.x new file mode 100644 index 00000000..49f153e7 --- /dev/null +++ b/pkg/obsolete/t_radplt.x @@ -0,0 +1,305 @@ +include <imhdr.h> +include <error.h> +include <mach.h> +include <gset.h> + +define EXTRA_HT 0.1 +define SZ_TITLE 512 + +# T_RADPLT -- Generate a radial profile plot around a star center. + +procedure t_radplt() + +char ifile[SZ_FNAME] +int infile, nfiles + +pointer im +int cboxsize, rboxsize +real xinit, yinit, xcntr, ycntr + +int clpopni(), clplen(), clgfil() +int clgeti() +real clgetr() +pointer immap() + +begin + # Get file names + infile = clpopni ("input") + nfiles = clplen (infile) + + # Get x and y initial + xinit = clgetr ("x_init") + yinit = clgetr ("y_init") + + # Get box size to use for centering + cboxsize = clgeti ("cboxsize") + + # Get box size to use for radial plot + rboxsize = clgeti ("rboxsize") + + # Loop over all images + while (clgfil (infile, ifile, SZ_FNAME) != EOF) { + iferr (im = immap (ifile, READ_ONLY, 0)) { + call eprintf ("[%s] not found\n") + call pargstr (ifile) + next + } + + # Find star center + call mpc_cntr (im, xinit, yinit, cboxsize, xcntr, ycntr) + + # Plot profile + call mpc_rplot (im, ifile, xcntr, ycntr, rboxsize) + + call printf ("[%s] x:%7.2f y:%7.2f\n") + call pargstr (ifile) + call pargr (xcntr) + call pargr (ycntr) + + call imunmap (im) + } +end + + +# MPC_CNTR -- Compute star center using MPC algorithm. + +procedure mpc_cntr (im, xstart, ystart, boxsize, xcntr, ycntr) + +pointer im +real xstart, ystart +int boxsize +real xcntr, ycntr + +int x1, x2, y1, y2, half_box +int ncols, nrows, nx, ny, try +real xinit, yinit +pointer bufptr, sp, x_vect, y_vect +int imgs2r() + +begin + half_box = (boxsize - 1) / 2 + xinit = xstart + yinit = ystart + + # Mark region to extract - use box size + ncols = IM_LEN (im, 1) + nrows = IM_LEN (im, 2) + try = 0 + + repeat { + x1 = amax1 (xinit - half_box, 1.0) +0.5 + x2 = amin1 (xinit + half_box, real(ncols)) +0.5 + y1 = amax1 (yinit - half_box, 1.0) +0.5 + y2 = amin1 (yinit + half_box, real(nrows)) +0.5 + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + + # Extract region around center + bufptr = imgs2r (im, x1, x2, y1, y2) + + # Collapse to two 1-D arrays + call smark (sp) + call salloc (x_vect, nx, TY_REAL) + call salloc (y_vect, ny, TY_REAL) + + call aclrr (Memr[x_vect], nx) + call aclrr (Memr[y_vect], ny) + + # Sum all rows + call mpc_rowsum (Memr[bufptr], Memr[x_vect], nx, ny) + + # Sum all columns + call mpc_colsum (Memr[bufptr], Memr[y_vect], nx, ny) + + # Find centers + call mpc_getcenter (Memr[x_vect], nx, xcntr) + call mpc_getcenter (Memr[y_vect], ny, ycntr) + + # Add in offsets + xcntr = xcntr + x1 + ycntr = ycntr + y1 + + call sfree (sp) + try = try + 1 + if (try == 1) { + if ((abs(xcntr-xinit) > 1.0) || (abs(ycntr-yinit) > 1.0)) { + xinit = xcntr + yinit = ycntr + } + } else + break + } +end + + +# MPC_RPLOT -- Plot intensity as a function of radial distance. + +procedure mpc_rplot (im, imname, xcntr, ycntr, rboxsize) + +pointer im +char imname[ARB] +real xcntr, ycntr +int rboxsize + +int x1, x2, y1, y2, half_box +pointer bufptr, title, sp, gp, op +int ncols, nrows, nx, ny, i, j +real xinit, yinit, radval, intval, ymin, ymax, xlen +int imgs2r(), strlen() +pointer gopen() + +begin + call smark (sp) + call salloc (title, SZ_TITLE, TY_CHAR) + + half_box = (rboxsize - 1) / 2 + xinit = xcntr + yinit = ycntr + + # Mark region to extract - use box size + ncols = IM_LEN(im,1) + nrows = IM_LEN(im,2) + + x1 = amax1 (xinit - half_box, 1.0) +0.5 + x2 = amin1 (xinit + half_box, real(ncols)) +0.5 + y1 = amax1 (yinit - half_box, 1.0) +0.5 + y2 = amin1 (yinit + half_box, real(nrows)) +0.5 + nx = x2 - x1 + 1 + ny = y2 - y1 + 1 + + # Extract region around center. + bufptr = imgs2r (im, x1, x2, y1, y2) + + # Begin plotting. + gp = gopen ("stdgraph", NEW_FILE, STDGRAPH) + + call mpc_aminmax (Memr[bufptr], nx, ny, ymin, ymax) + ymax = ymax + EXTRA_HT * (ymax-ymin) + ymin = ymin - EXTRA_HT * (ymax-ymin) + + xlen = 1.5 * rboxsize / 2 + call gswind (gp, 0.0, xlen, ymin, ymax) + + call sysid (Memc[title], SZ_LINE) + op = title + strlen (Memc[title]) + call sprintf (Memc[op], SZ_TITLE-SZ_LINE, + "\nRadial Plot of %s at [%0.2f,%0.2f]\n") + call pargstr (imname) + call pargr (xcntr) + call pargr (ycntr) + + call glabax (gp, Memc[title], "Pixels", "Counts") + + do i = 1, ny + do j = 1, nx { + call mpc_radius (Memr[bufptr], nx, ny, j, i, xcntr-x1+1, + ycntr-y1+1, radval, intval) + call gmark (gp, radval, intval, GM_PLUS, -.005*xlen, + -0.007*(ymax-ymin)) + } + + call gclose (gp) + call sfree (sp) +end + + +# AMINMAX -- Compute min and max of two-d array. + +procedure mpc_aminmax (a, nx, ny, ymin, ymax) + +int nx, ny +real a[nx,ny] +real ymin, ymax + +int i, j + +begin + ymin = a[1,1] + ymax = ymin + + do i = 1, ny + do j = 1, nx { + ymin = amin1 (ymin, a[j,i]) + ymax = amax1 (ymax, a[j,i]) + } +end + + +# RADIUS -- Compute radius from center. + +procedure mpc_radius (a, nx, ny, i, j, xc, yc, radval, intval) + +real a[nx, ny] +int nx, ny, i, j +real xc, yc, dx, dy, radval, intval + +begin + dx = xc - i + dy = yc - j + radval = sqrt (dx**2 + dy**2) + intval = a[i,j] +end + + +# ROWSUM -- Sum all rows in a raster + +procedure mpc_rowsum (v, row, nx, ny) + +int nx, ny +real v[nx,ny] +real row[ARB] + +int i, j + +begin + do i = 1, ny + do j = 1, nx + row[j] = row[j] + v[j,i] +end + + +# COLSUM -- Sum all columns in a raster. + +procedure mpc_colsum (v, col, nx, ny) + +int nx, ny +real v[nx,ny] +real col[ARB] + +int i, j + +begin + do i = 1, ny + do j = 1, nx + col[j] = col[j] + v[i,j] +end + + +# GETCENTER -- Compute center of gravity of array. + +procedure mpc_getcenter (v, nv, vc) + +real v[ARB] +int nv +real vc + +int i +real sum1, sum2, sigma, cont + +begin + # Assume continuum level is at endpoints + # Compute first moment + sum1 = 0.0 + sum2 = 0.0 + + call aavgr (v, nv, cont, sigma) + + do i = 1, nv + if (v[i] > cont) { + sum1 = sum1 + (i-1) * (v[i] - cont) + sum2 = sum2 + (v[i] - cont) + } + + # Determine center + vc = sum1 / sum2 +end diff --git a/pkg/obsolete/x_obsolete.x b/pkg/obsolete/x_obsolete.x new file mode 100644 index 00000000..7f0cf71d --- /dev/null +++ b/pkg/obsolete/x_obsolete.x @@ -0,0 +1,8 @@ +task imtitle = t_imtitle, + mkhistogram = t_mkhistogram, + oimcombine = t_imcombine, + ofixpix = t_fixpix, + oimstatistics = t_oimstatistics, + orfits = t_rfits, + owfits = t_wfits, + radplt = t_radplt |