diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/images/imfit | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/images/imfit')
-rw-r--r-- | pkg/images/imfit/Revisions | 2025 | ||||
-rw-r--r-- | pkg/images/imfit/doc/fit1d.hlp | 177 | ||||
-rw-r--r-- | pkg/images/imfit/doc/imsurfit.hlp | 226 | ||||
-rw-r--r-- | pkg/images/imfit/doc/lineclean.hlp | 129 | ||||
-rw-r--r-- | pkg/images/imfit/fit1d.par | 16 | ||||
-rw-r--r-- | pkg/images/imfit/imfit.cl | 13 | ||||
-rw-r--r-- | pkg/images/imfit/imfit.hd | 10 | ||||
-rw-r--r-- | pkg/images/imfit/imfit.men | 3 | ||||
-rw-r--r-- | pkg/images/imfit/imfit.par | 1 | ||||
-rw-r--r-- | pkg/images/imfit/imsurfit.par | 24 | ||||
-rw-r--r-- | pkg/images/imfit/lineclean.par | 13 | ||||
-rw-r--r-- | pkg/images/imfit/mkpkg | 5 | ||||
-rw-r--r-- | pkg/images/imfit/src/fit1d.x | 597 | ||||
-rw-r--r-- | pkg/images/imfit/src/imsurfit.h | 40 | ||||
-rw-r--r-- | pkg/images/imfit/src/imsurfit.x | 1172 | ||||
-rw-r--r-- | pkg/images/imfit/src/mkpkg | 15 | ||||
-rw-r--r-- | pkg/images/imfit/src/pixlist.h | 11 | ||||
-rw-r--r-- | pkg/images/imfit/src/pixlist.x | 369 | ||||
-rw-r--r-- | pkg/images/imfit/src/ranges.x | 524 | ||||
-rw-r--r-- | pkg/images/imfit/src/t_imsurfit.x | 400 | ||||
-rw-r--r-- | pkg/images/imfit/src/t_lineclean.x | 270 |
21 files changed, 6040 insertions, 0 deletions
diff --git a/pkg/images/imfit/Revisions b/pkg/images/imfit/Revisions new file mode 100644 index 00000000..7ff95abd --- /dev/null +++ b/pkg/images/imfit/Revisions @@ -0,0 +1,2025 @@ +.help revisions Jan97 images.imfit +.nf +=============================== +Package Reorganization +=============================== + +pkg/images/imarith/t_imsum.x +pkg/images/imarith/t_imcombine.x +pkg/images/doc/imsum.hlp +pkg/images/doc/imcombine.hlp + Provided options for USHORT data. (12/10/96, Valdes) + +pkg/images/imarith/icsetout.x +pkg/images/doc/imcombine.hlp + A new option for computing offsets from the image WCS has been added. + (11/30/96, Valdes) + +pkg/images/imarith/t_imcombine.x +pkg/images/imarith/icombine.gx + Changed the error checking to catch additional errors relating to too + many files. (11/12/96, Valdes) + +pkg/images/imarith/icsort.gx + There was an error in the ic_2sort routine when there are exactly + three images that one of the explicit cases did not properly keep + the image identifications. See buglog 344. (8/1/96, Valdes) + +pkg/images/filters/median.x + The routine mde_yefilter was being called with the wrong number of + arguments. + (7/18/96, Davis) + +pkg/images/imarith/t_imcombine.x +pkg/images/imarith/icombine.gx +pkg/images/imarith/icimstack.x + +pkg/images/imarith/iclog.x +pkg/images/imarith/mkpkg +pkg/images/doc/imcombine.hlp + The limit on the maximum number of images that can be combined, set by + the maximum number of logical file descriptors, has been removed. If + the condition of too many files is detected the task now automatically + stacks all the images in a temporary image and then combines them with + the project option. + (5/14/96, Valdes) + +pkg/images/geometry/xregister/rgxfit.x + Changed several Memr[] references to Memi[] in the rg_fit routine. + This bug was causing a floating point error in the xregister task + on the Dec Alpha if the coords file was defined, and could potentially + cause problems on other machines. + (Davis, April 3, 1996) + +pkg/images/geometry/t_geotran.x +pkg/images/geometry/geograph.x +pkg/images/doc/geomap.hlp + Corrected the definition of skew in the routines which compute a geometric + interpretation of the 6-coefficient fit, which compute the coefficients + from the geometric parameters, and in the relevant help pages. + (2/19/96, Davis) + +pkg/images/median.par +pkg/images/rmedian.par +pkg/images/mode.par +pkg/images/rmode.par +pkg/images/fmedian.par +pkg/images/frmedian.par +pkg/images/fmode.par +pkg/images/frmode.par +pkg/images/doc/median.hlp +pkg/images/doc/rmedian.hlp +pkg/images/doc/mode.hlp +pkg/images/doc/rmode.hlp +pkg/images/doc/fmedian.hlp +pkg/images/doc/frmedian.hlp +pkg/images/doc/fmode.hlp +pkg/images/doc/frmode.hlp +pkg/images/filters/t_median.x +pkg/images/filters/t_rmedian.x +pkg/images/filters/t_mode.x +pkg/images/filters/t_rmode.x +pkg/images/filters/t_fmedian.x +pkg/images/filters/t_frmedian.x +pkg/images/filters/t_fmode.x +pkg/images/filters/t_frmode.x + Added a verbose parameter to the median, rmedian, mode, rmode, fmedian, + frmedian, fmode, and frmode tasks. (11/27/95, Davis) + +pkg/images/geometry/doc/geotran.hlp + Fixed an error in the help page for geotran. The default values for + the xscale and yscale parameters were incorrectly listed as INDEF, + INDEF instead of 1.0, 1.0. (11/14/95, Davis) + +pkg/images/imarith/icpclip.gx + Fixed a bug where a variable was improperly used for two different + purposes causing the algorithm to fail (bug 316). (10/19/95, Valdes) + +pkg/images/doc/imcombine.hlp + Clarified a point about how the sigma is calculated with the SIGCLIP + option. (10/11/95, Valdes) + +pkg/images/imarith/icombine.gx + To deal with the case of readnoise=0. and image data which has points with + negative mean or median and very small minimum readnoise is set + internally to avoid computing a zero sigma and dividing by it. This + applies to the noise model rejection options. (8/11/95, Valdes) + +pkg/images/frmedian.hlp +pkg/images/frmode.hlp +pkg/images/rmedian.hlp +pkg/images/rmode.hlp +pkg/images/frmedian.par +pkg/images/frmode.par +pkg/images/rmedian.par +pkg/images/rmode.par +pkg/images/filters/frmedian.h +pkg/images/filters/frmode.h +pkg/images/filters/rmedian.h +pkg/images/filters/rmode.h +pkg/images/filters/t_frmedian.x +pkg/images/filters/t_frmode.x +pkg/images/filters/t_rmedian.x +pkg/images/filters/t_rmode.x +pkg/images/filters/frmedian.x +pkg/images/filters/frmode.x +pkg/images/filters/rmedian.x +pkg/images/filters/rmode.x +pkg/images/filters/med_utils.x + Added new ring median and modal filtering tasks frmedian, rmedian, + frmode, and rmode to the images package. + (6/20/95, Davis) + +pkg/images/fmedian.hlp +pkg/images/fmode.hlp +pkg/images/median.hlp +pkg/images/mode.hlp +pkg/images/fmedian.par +pkg/images/fmode.par +pkg/images/median.par +pkg/images/mode.par +pkg/images/filters/fmedian.h +pkg/images/filters/fmode.h +pkg/images/filters/median.h +pkg/images/filters/mode.h +pkg/images/filters/t_fmedian.x +pkg/images/filters/t_fmode.x +pkg/images/filters/t_median.x +pkg/images/filters/t_mode.x +pkg/images/filters/fmedian.x +pkg/images/filters/fmode.x +pkg/images/filters/median.x +pkg/images/filters/mode.x +pkg/images/filters/fmd_buf.x +pkg/images/filters/fmd_hist.x +pkg/images/filters/fmd_maxmin.x +pkg/images/filters/med_buf.x +pkg/images/filters/med_sort.x + Added minimum and maximum good data parameters to the fmedian, fmode, + median, and mode filtering tasks. Removed the 64X64 kernel size limit + in the median and mode tasks. Replaced the common blocks with structures + and .h files. + (6/20/95, Davis) + +pkg/images/geometry/t_geotran.x +pkg/images/geometry/geotran.x +pkg/images/geometry/geotimtran.x + Fixed a bug in the buffering of the x and y coordinate surface interpolants + which can cause a memory corruption error if, nthe nxsample or nysample + parameters are > 1, and the nxblock or nyblock parameters are less + than the x and y dimensions of the input image. Took the opportunity + to clean up the code. + (6/13/95, Davis) + +======= +V2.10.4 +======= + +pkg/images/geometry/t_geomap.x + Corrected a harmless typo in the code which determines the minimum + and maximum x values and improved the precision of the test when the + input is double precision. + (4/18/95, Davis) + +pkg/images/doc/fit1d.hlp + Added a description of the interactive parameter to the fit1d help page. + (4/17/95, Davis) + +pkg/images/imarith/t_imcombine.x + If an error occurs while opening an input image header the error + recovery will close all open images and then propagate the error. + For the case of running out of file descriptors with STF format + images this will allow the error message to be printed rather + than the error code. (4/3/95, Valdes) + +pkg/images/geometry/xregister/t_xregister.x + Added a test on the status code returned from the fitting routine so + the xregister tasks does not go ahead and write an output image when + the user quits the task in in interactive mode. + (3/31/95, Davis) + +pkg/images/imarith/icscale.x +pkg/images/doc/imcombine.hlp + The behavior of the weights when using both multiplicative and zero + point scaling was incorrect; the zero levels have to account for + the scaling. (3/27/95, Valdes) + +pkg/images/geometry/xregister/rgxtools.x + Changed some amovr and amovi calls to amovkr and amovki calls. + (3/15/95, Davis) + +pkg/images/geometry/t_imshift.x +pkg/images/geometry/t_magnify.x +pkg/images/geometry/geotran.x +pkg/images/geometry/xregister/rgximshift.x + The buffering margins set for the bicubic spline interpolants were + increased to improve the flux conservation properties of the interpolant + in cases where the data is undersampled. (12/6/94, Davis) + +pkg/images/xregister/rgxbckgrd.x + In several places the construct array[1++nx-wborder] was being used + instead of array[1+nx-wborder]. Apparently caused by a typo which + propagated through the code, the Sun compilers did not catch this, but + the IBM/RISC6000 compilers did. (11/16/94, Davis) + + +pkg/images/xregister.par +pkg/images/doc/xregister.hlp +pkg/images/geometry/xregister/t_xregister.x +pkg/images/geometry/xregister/rgxcorr.x +pkg/images/geometry/xregister/rgxicorr.x +pkg/images/geometry/xregister/rgxcolon.x +pkg/images/geometry/xregister/rgxdbio.x + The xregister task was modified to to write the output shifts file + in either text database format (the current default) or in simple text + format. The change was made so that the output of xregister could + both be edited more easily by the user and be used directly with the + imshift task. (11/11/94, Davis) + +pkg/images/imfit/fit1d.x + A Memc in the ratio output option was incorrectly used instead of Memr + when the bug fix of 11/16/93 was made. (10/14/94, Valdes) + +pkg/images/geometry/xregister/rgxcorr.x + The procedure rg_xlaplace was being incorrectly declared as an integer + procedure. + (8/1/94, Davis) + +pkg/images/geometry/xregister/rgxregions.x + The routine strncmp was being called (with a missing number of characters + argument) instead of strcmp. This was causing a bus error under solaris + but not sun os whenever the user set regions to "grid ...". (7/27/94 LED) + +pkg/images/tv/imexaine/ierimexam.x + The Gaussian fitting can return a negative sigma**2 which would cause + an FPE when the square root is taken. This will only occur when + there is no reasonable signal. The results of the gaussian fitting + are now set to INDEF if this unphysical result occurs. (7/7/94, Valdes) + +pkg/images/geometry/geofit.x + A routine expecting two char arrays was being passed two real arrays + instead resulting in a segmentation violation if calctype=real + and reject > 0. + (6/21/94, Davis) + +pkg/images/imarith/t_imarith.x + IMARITH now deletes the CCDMEAN keyword if present. (6/21/94, Valdes) + +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icsclip.gx + 1. The restoration of deleted pixels to satisfy the nkeep parameter + was being done inside the iteration loop causing the possiblity + of a non-terminating loop; i.e. pixels are rejected, they are + restored, and the number left then does not statisfy the termination + condition. The restoration step was moved following the iterative + rejection. + 2. The restoration was also incorrectly when mclip=no and could + lead to a segmentation violation. + (6/13/94, Valdes) + +pkg/images/geometry/xregister/rgxicorr.x + The path names to the xregister task interactive help files was incorrect. + (6/13/94, Davis) + +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icsclip.gx + Found and fixed another typo bug. (6/7/94, Valdes/Zhang) + +pkg/images/imarith/icscale.x + The sigma scaling flag, doscale1, would not be set in the case of + a mean offset of zero though the scale factors could be different. + (5/25/94, Valdes/Zhang) + +pkg/images/imarith/icsclip.gx + There was a missing line: l = Memi[mp1]. (5/25/94, Valdes/Zhang) + +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icsclip.gx + The reordering step when a central median is used during rejection + but the final combining is average was incorrect if the number + of rejected low pixels was greater than the number of pixel + number of pixels not rejected. (5/25/94, Valdes) + +pkg/images/geometry/t_geotran.x + In cases where there was no input geomap database, geotran was + unnecessarily overiding the size of the input image requested by the + user if the size of the image was bigger than the default output size + (the size of the output image which would include all the input image + pixels is no user shifts were applied). + (5/10/94, Davis) + +pkg/images/imarith/icscale.x +pkg/images/imarith/t_imcombine.x + 1. There is now a warning error if the scale, zero, or weight type + is unknown. + 2. An sfree was being called before the allocated memory was finished + being used. + (5/2/94, Valdes) + +pkg/images/tv/imexaine/ierimexam.x + For some objects the moment analysis could fail producing a floating + overflow error in imexamine, because the code was trying to use + INDEF as the initial value of the object fwhm. Changed the gaussian + fitting code to use a fraction of the fitting radius as the initial value + for the fitted full-width half-maximum in cases where the moment analysis + cannot compute an initial value. + (4/15/94 LED) + +pkg/images/imarith/iclog.x + Changed the mean, median, mode, and zero formats from 6g to 7.5g to + insure 5 significant digits regardless of signs and decimal points. + (4/13/94, Valdes) + +pkg/images/doc/imcombine.hlp + Tried again to clarify the scaling as multiplicative and the offseting + as additive for file input and for log output. (3/22/94, Valdes) + +pkg/images/imarith/iacclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/iscclip.gx + The image sigma was incorrectly computed when an offset scaling is used. + (3/8/94, Valdes) + +pkg/images/doc/imcombine.hlp + The MINMAX example confused low and high. (3/7/94, Valdes) + +pkg/images/geometry/t_geomap.x +pkg/images/geometry/geofit.x +pkg/images/geometry/geograph.x + Fixed a bug in the geomap code which caused the linear portion of the transformation + to be computed incorrectly if the x and y fits had a different functional form. + (12/29/93, Davis) + +pkg/images/imarith/t_imcombine.x +pkg/images/imcombine.par +pkg/images/do/imcombine.hlp + The output pixel datatypes now include unsigned short integer. + (12/4/93, Valdes) + +pkg/images/doc/imcombine.hlp + Fixed an error in the example of offseting. (11/23/93, Valdes) + +pkg/images/imfit/fit1d.x + When doing operations in place the input and output buffers are the + same and the difference and ratio operations assumed they were not + causing the final results to be wrong. (11/16/93, Valdes) + +pkg/images/imarith/t_imarith.x +pkg/images/doc/imarith.hlp + If no calculation type is specified then it will be at least real + for a division. Since the output pixel type defaults to the + calculation type if not specified this will also result in a + real output if dividing two integer images. (11/12/93, Valdes) + +pkg/images/imarith/icgrow.gx +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icsclip.gx +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/t_imcombine.x +pkg/images/doc/imcombine.hlp + If there were fewer initial pixels than specified by nkeep then the + task would attempt to add garbage data to achieve nkeep pixels. This + could occur when using offsets, bad pixel masks, or thresholds. The + code was changed to check against the initial number of pixels rather + than the number of images. Also a negative nkeep is no longer + converted to a positive value based on the number of images. Instead + it specifies the maximum number of pixels to reject from the initial + set of pixels. (11/8/93, Valdes) + +======= +V2.10.2 +======= + +pkg/images/imarith/icsetout.x + Added MWCS calls to update the axis mapping when using the project + option in IMCOMBINE. (10/8/93, Valdes) + +pkg$images/imarith/icscale.x +pkg$images/doc/imcombine.hlp + The help indicated that user input scale or zero level factors + by an @file or keyword are multiplicative and additive while the + task was using then as divisive and subtractive. This was + corrected to agree with the intend of the documentation. + Also the factors are no longer normalized. (9/24/93, Valdes) + +pkg$images/imarith/icsetout.x + The case in which absolute offsets are specified but the offsets are + all the same did not work correctly. (9/24/93, Valdes) + +pkg$images/imfit/imsurfit.h +pkg$images/imfit/t_imsurfit.x +pkg$images/imfit/imsurfit.x +pkg$images/lib/ranges.x + Fixed two bugs in the imsurfit task bad pixel rejection code. For low + k-sigma rejections factors the bad pixel list could overflow resulting + in a segmentation violation or a hung task. Overlapping ranges were + not being decoded into a bad pixel list properly resulting in + oscillating bad pixel rejection behavior where certain groups of + bad pixels were alternately being included and excluded from the fit. + Both bugs are fixed in iraf 2.10.3 + (9/21/93, Davis) + +pkg$images/doc/imcombine.hlp + Clarified how bad pixel masks work with the "project" option. + (9/13/93, Valdes) + +pkg$images/imfit/fit1d.x + When the input and output images are the same there was an typo error + such that the output was opened separately but then never unmapped + resulting in the end of the image not being updated. (8/6/93, Valdes) + +pkg$images/imarith/t_imcombine.x + The algorithm for making sure there are enough file descriptors failed + to account for the need to reopen the output image header for an + update. Thus when the number of input images + output images + logfile + was exactly 60 the task would fail. The update occurs when the output + image is unmapped so the solution was to close the input images first + except for the first image whose pointer is used in the new copy of the + output image. (8/4/93, Valdes) + +pkg$images/filters/t_mode.x +pkg$images/filters/t_median.x + Fixed a bug in the error trapping code in the median and mode tasks. + The call to eprintf contained an extra invalid error code agument. + (7/28/93, Davis) + +pkg$images/geometry/geomap.par +pkg$images/geometry/t_geomap.x +pkg$images/geometry/geogmap.x +pkg$images/geometry/geofit.x + Fixed a bug in the error handling code in geomap which was producing + a segmentation violation on exit if the user's coordinate list + had fewer than 3 data points. Also improved the error messages + presented to the user in both interactive and non-interactive mode. + (7/7/93, Davis) + +pkg$images/imarith/icgdata.gx + There was an indexing error in setting up the ID array when using + the grow option. This caused the CRREJECT/CCDCLIP algorithm to + fail with a floating divide by zero error when there were non-zero + shifts. (5/26/93, Valdes) + +pkg$images/imarith/icmedian.gx + The median calculation is now done so that the original input data + is not lost. This slightly greater inefficiency is required so + that an output sigma image may be computed if desired. (5/10/93, Valdes) + +pkg$images/geometry/t_imshift.x + Added support for type ushort to the imshift task in cases where the + pixel shifts are integral. + (5/8/93, Davis) + +pkg$images/doc/rotate.hlp + Fixed a bug in the rotate task help page which implied that automatic + image size computation would occur if ncols or nlines were set no 0 + instead of ncols and nlines. + (4/17/93, Davis) + +pkg$images/imarith/imcombine.gx + There was no error checking when writing to the output image. If + an error occurred (the example being when an imaccessible imdir was + set) obscure messages would result. Errchks were added. + (4/16/93, Valdes) + +pkg$images/doc/gauss.hlp + Fixed 2 sign errors in the equations in the documentation describing + the elliptical gaussian fucntion. + (4/13/92, Davis) + +pkg/images/imutil/t_imslice.x + Removed an error check in the imslice task, which was preventing it from + being used to reduce the dimensionality of images where the length of + the slice dimension is 1.0. + (2/16/83, Davis) + +pkg/images/filters/fmedian.x + The fmedian task was printing debugging information under iraf 2.10.2. + (1/25/93, Davis) + +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icsclip.gx + When using mclip=yes and when more pixels are rejected than allowed by + the nkeep parameter there was a subtle bug in how the pixels are added + back which can result in a segmentation violation. + if (nh == n2) ==> if (nh == n[i]) + (1/20/93, Valdes) + + +======= +V2.10.1 +======= + +pkg/images/imarith/t_imcombine.x +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icgrow.gx +pkg/images/imarith/iclog.x +pkg/images/imarith/icombine.com +pkg/images/imarith/icombine.gx +pkg/images/imarith/icombine.h +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icscale.x +pkg/images/imarith/icsclip.gx +pkg/images/imarith/icsetout.x +pkg/images/imcombine.par +pkg/images/doc/combine.hlp + The weighting was changed from using the square root of the exposure time + or image statistics to using the values directly. This corresponds + to variance weighting. Other options for specifying the scaling and + weighting factors were added; namely from a file or from a different + image header keyword. The \fInkeep\fR parameter was added to allow + controlling the maximum number of pixels to be rejected by the clipping + algorithms. The \fIsnoise\fR parameter was added to include a sensitivity + or scale noise component to the noise model. Errors will now delete + the output image. + (9/30/92, Valdes) + +pkg/images/imutil/imcopy.x + Added a call to flush after the status line printout so that the output + will appear immediately. (8/19/92, Davis) + +pkg/images/filters/mkpkg +pkg/images/filters/t_fmedian.x +pkg/images/filters/fmedian.x +pkg/images/filters/fmd_buf.x +pkg/images/filters/fmd_maxmin.x + The fmedian task could crash with a segmentation violation if mapping + was turned off (hmin = zmin and hmax = zmax) and the input image + contained data outside the range defined by zmin and zmax. (8/18/92, Davis) + +pkg/images/imarith/icaclip.gx +pkg/images/imarith/iccclip.gx +pkg/images/imarith/icpclip.gx +pkg/images/imarith/icsclip.gx + There was a very unlikely possibility that if all the input pixels had + exactly the same number of rejected pixels the weighted average would + be done incorrectly because the dflag would not be set. (8/11/92, Valdes) + +pkg/images/imarith/icmm.gx + This procedure failed to set the dflag resulting in the weighted average + being computed in correctly. (8/11/92, Valdes) + +pkg/images/imfit/fit1d.x + At some point changes were made but not documented dealing with image + sections on the input/output. The changes seem to have left off the + final step of opening the output image using the appropriate image + sections. Because of this it is an error to use an image section + on an input image when the output image is different; i.e. + + cl> fit1d dev$pix[200:400,*] junk + + This has now been fixed. (8/10/92, Valdes) + +pkg/images/imarith/icscales.x + The zero levels were incorrectly scaled twice. (8/10/92, Valdes) + +pkg/images/imarith/icstat.gx + Contained the statement + nv = max (1., (Memi[v2+i] - Memi[v1+i]) / Memi[dv+i] + 1) + which is max(real,int). Changed the 1. to a 1. (8/10/92, Valdes) + +pkg$images/imarith/icaclip.gx +pkg$images/imarith/iccclip.gx +pkg$images/imarith/icsclip.gx + These files contained multiple cases (ten or so) of constructs such as + "max (1., ...)" or "max (0., ...)" where the ... could be either real + or double. In the double cases the DEC compiler complained about a + type mismatch since 1. is real. (8/10/92, Valdes) + +pkg$images/imfit/t_imsurfit.x + Fixed a bug in the section reading code. Imsurfit is supposed to switch + the order of the section delimiters in x and y if x2 < x1 or y2 < 1. + Unfortunately the y test was actually "if (y2 < x1)" instead of + "if (y2 < y1)". Whether or not the code actually works correctly + depends on the value of x1 relative to y2. This bug was not present + in 2.9.1 but is present in subsequent releases. (7/30/92 LED) + +======= +V2.10.1 +======= + +pkg$images/filters/t_gauss.x + The case theta=90 and ratio > 0.0 but < 1.0 was producing an incorrect + convolution if bilinear=yes, because the major axis sigmas being + input along the x and y axes were sigma and ratio * sigma respectively + instead of ratio * sigma and sigma in this case. + +pkg$images/imutil/imcopy.x + Modified imcopy to write its verbose output to STDOUT instead of + STDERR. (6/24/92, Davis) + +pkg$images/imarith/imcombine.gx + The step where impl1$t is called to check if there is enough memory + did not set the return buffer because the values are irrelevant for + this check. However, depending on history, this buffer could have + arbitrary values and later when IMIO attempts to flush this buffer, + at least in the case of image type coersion, cause arithmetic errors. + The fix was to clear the returned buffers. (4/27/92, Valdes) + +pkg$images/imutil/t_imstack.x + Modified the imslice task to read the old and write a new axis map. + (4/23/92, Davis) + +pkg$images/geometry/t_imslice.x + Modified the imslice task to read the old and write a new axis map. + (4/23/92, Davis) + +pkg$images/geometry/t_blkavg.x +pkg$images/geometry/t_blkrep.x + Modified the calls to mw_shift and mw_scale to explicitly set the + number of logical axes instead of using the default of 0. + (4/23/92, Davis) + +pkg$images/geometry/t_imtrans.x + Modified imtranspose so that it correctly picks up the axis map + and writes it to the output image wcs. (4/23/92, Davis) + +pkg$images/register.par +pkg$images/geotran.par +pkg$images/doc/register.hlp +pkg$images/doc/geotran.hlp + Changed the default values of the parameters xscale and yscale in + the register and geotran tasks from INDEF to 1.0 (4/23/92, Davis) + +pkg$images/geometry/t_imtrans.x +pkg$images/doc/imtranspose.hlp + Modified the imtranspose task so it does a true transpose of the + axes instead of simply modifying the lterm. (4/8/92, Davis) + +pkg$images/iminfo/listpixels.x + Added the formats parameter for formatting the output pixel coordinates + to the listpixels task. These formats take precedence over the formats + stored in the WCS in the image header and the previous default format. + (4/7/92, Davis) + +pkg$images/imutil/t_imstack.x + Added wcs support to the imstack task. (4/2/92, Davis) + +pkg$images/iminfo/listpixels.x + Modified listpixels so that it will work correctly if the dimension + of the wcs is less than the dimension of the image. (3/16/92, Davis) + +pkg$images/geometry/t_geotran.x + Modified the rotate, imlintran, register and geotran tasks wcs updating + code to deal correclty with dimensionally reduced data. (3/16/92, Davis) + +pkg$images/imarith/icalip.gx +pkg$images/imarith/icclip.gx +pkg$images/imarith/ipslip.gx +pkg$images/imarith/icslip.gx +pkg$images/imarith/icmedian.gx + The median calculation with an even number of points for short data + could overflow (addition of two short values) and be incorrect. + (3/16/92, Valdes) + +pkg$images/geometry/t_blkavg.x +pkg$images/geometry/t_blkrep.x + 1. Improved the precision of the blkavg task wcs updating code. + 2. Changed the blkrep task wcs updating code so that it is consistent + with blkavg. This means that a blkrep command followed by a blkavg + command or vice versa will return the original coordinate system + to within machine precision. (3/16/92, Davis) + +pkg$images/iminfo/listpixels.x + Modified listpixels to print out an error if it could not open the + wcs in the image. (3/15/92, Davis) + +pkg$images/geometry/t_magnify.x + Fixed a bug in the magnify task wcs updating code which was not + working correctly for dimensionally reduced images. (3/15/92, Davis) + +pkg$images/geometry/t_imtrans.x + Fixed a bug in the imtranspose task wcs updating code which was not + working correctly for dimensionally reduced images. (3/14/92, Davis) + +pkg$images/imarith/icalip.gx +pkg$images/imarith/icclip.gx +pkg$images/imarith/icslip.gx + There was a bug allowing the number of valid pixels counter to become + negative. Also there was a step which should not be done if the + number of valid pixels is less than 1; i.e. all pixels rejected. + A test was put in to skip this step. (3/13/92, Valdes) + +pkg$images/iminfo/t_imslice.x +pkg$images/doc/imslice.hlp + Added wcs support to the imslice task. + (3/12/92, Davis) + +pkg$images/iminfo/t_imstat.x + Fixed a bug in the code for computing the standard deviation, kurtosis, + and skew, wherein precision was being lost because two of the intermediate + variables in the computation were real instead of double precision. + (3/10/92, Davis) + +pkg$images/iminfo/listpixels.x + 1. Modified listpixels task to use the MWCS axis "format" attributes + if they are present in the image header. + 2. Added support for dimensionally reduced images, i.e. + images which are sections of larger images and whose coordinate + transformations depend on the reduced axes, to the listpixels task. + (3/6/92, Davis) + +pkg$images/imarith/t_imcombine.x +pkg$images/imarith/icsetout.x + Changed error messages to say IMCOMBINE instead of ICOMBINE. + (3/2/92, Valdes) + +pkg$images/imarith/iclog.x + Added listing of read noise and gain. (2/10/92, Valdes) + +pkg$images/imarith/icscale.x +pkg$images/imarith/icpclip.gx + 1. Datatype declaration for asumi was incorrect. + 2. Reduced the minimum number of images allowed for PCLIP to 3. + (1/7/92, Valdes) + +pkg$images/imarith/icgrow.gx + The first pixel to be checked was incorrectly set to 0 instead of 1 + resulting in a segvio when using the grow option. (12/6/91, Valdes) + +pkg$images/imarith/icgdata.gx +pkg$images/imarith/icscale.x + Fixed datatype declaration errors found by SPPLINT. (11/22/91, Valdes) + +pkg$images/iminfo/t_imstat.x + Fixed a bug in the kurtosis computation found by ST. + (Davis 10/11/91) + +pkg$images/iminfo/t_imstat.x +pkg$images/doc/imstat.hlp + Corrected a bug in the mode computation in imstatistics. The parabolic + interpolation correction for computing the histogram peak was being + applied in the wrong direction. Note that for dev$pix the wrong answer + is actually closer to the expected answer than the correct answer + due to binning effects. + (Davis 9/24/91) + +pkg$images/filters/t_gauss.x + The code which computes the gaussian kernel was producing a divide by + zero error if ratio=0.0 and bilinear=yes (2.10 version only). + (Davis 9/18/91) + +pkg$images/doc/magnify.hlp + Corrected a bug in the magnify help page. + (Davis 9/18/91) + +pkg$images/imarith/icsclip.gx +pkg$images/imarith/icaclip.gx +pkg$images/imarith/iccclip.gx + There was a typo, Memr[d[k]+k] --> Memr[d[j]+k]. (9/17/91, Valdes) + +pkg$images/imarith/icstat.gx +pkg$images/imarith/icmask.x + The offsets were used improperly in computing image statistics. + (Valdes, 9/17/91) + +pkg$images/geometry/t_imshift.x + The shifts file pointer was not being correctly initialized to NULL + in the case where no shifts file was declared. When the task + was invoked repeatedly from a script, this could result in an array being + referenced, for which space had not been previously allocated. + (Davis 7/29/91) + +pkg$images/imarith/imc* - +pkg$images/imarith/ic* + +pkg$images/imarith/t_imcombine.x +pkg$images/imarith/mkpkg +pkg$images/imarith/generic/mkpkg +pkg$images/imcombine.par +pkg$images/doc/imcombine.hlp + Replaced old version of IMCOMBINE with new version supporting masks, + offsets, and new algorithms. (Valdes 7/19/91) + +pkg$images/iminfo/imhistogram.x + Imhistogram has been modified to print the value of the middle of + histogram bin instead of the left edge if the output type is list + instead of plot. (Davis 6/11/91) + +pkg$images/t_imsurfit.x + Modified the sections file reading code to check the order of the + x1 x2 y1 y2 parameters and switch (x1,x2) or (y1,y2) if x2 < x1 or + y2 < y1 respectively. (Davis 5/28/91) + +pkg$images/listpixels.par +pkg$images/iminfo/listpixels.x +pkg$images/doc/listpixels.hlp + Modified the listpixels task to be able to print the pixel coordinates + in logical, physical or world coordinates. The default coordinate + system is still logical as before. (Davis 5/17/91) + +pkg$images/images.par +pkg$images/doc/minmax.hlp +pkg$images/imutil/t_minmax.x +pkg$images/imutil/minmax.x + Minmax was modified to do the minimum and maximum values computations + in double precision or complex instead of real if the input image + pixel type is double precision or complex. Note that the minimum and + maximum header values are still stored as real however. + (Davis 5/16/91) + +imarith/t_imarith.x + There was a missing statement to set the error flag if the image + dimensions did not match. (5/14/91, Valdes) + +doc/imarith.hlp + Fixed some formatting problems in the imarith help page. (5/2/91 Davis) + +imarith$imcombine.x + Changed the order in which images are unmapped to have the output images + closed last. This is to allow file descriptors for the temporary image + used when updating STF headers. (4/22/91, Valdes) + +pkg$images/geometry/t_blkavg.x +pkg$images/geometry/blkavg.gx +pkg$images/geometry/blkavg.x + The blkavg task was partially modified to support complex image data. + The full modifications cannot be made because of an error in abavx.x + and the missing routine absux.x. + (4/18/91 Davis) + +pkg$images/geometry/geofit.x + The x and y fits cross-terms switch was not being set correctly to "yes" + in the case where xxorder=2 and xyorder=2 or in the case where yxorder=2 + and yyorder=2. + (4/9/91 Davis) + +pkg$images/geometry/geogmap.x + Modified the line which prints the geometric parameters to use the + variable name xshift and yshift instead of delx and dely. + (4/9/91 Davis) + +pkg$images/imfit/imsurfit.x + Fixed a bug in the pixel rejection code which occurred when upper was > + 0.0 and lower = 0.0 or lower > 0 and upper = 0.0. The problem was that + the code was simply setting the rejection limits to the computed sigma + times the upper and lower parameters without checking for the 0.0 + condition first. In the first case this results in all points with + negative residuals being rejected and in the latter all points with + positive residuals are rejected. + (2/25/91 Davis) + +pkg$images/doc/hedit.hlp +pkg$images/doc/hselect.hlp +pkg$images/doc/imheader.hlp +pkg$images/doc/imgets.hlp + Added a reference to imgets in the SEE ALSO sections of the hedit and + hselect tasks. + Added a reference to hselect and hedit in the SEE ALSO sections of the + imheader and imgets tasks. + (2/22/91 Davis) + +pkg$images/gradient.hlp +pkg$images/laplace.hlp +pkg$images/gauss.hlp +pkg$images/convolve.hlp +pkg$images/gradient.par +pkg$images/laplace.par +pkg$images/gauss.par +pkg$images/convolve.par +pkg$images/t_gradient.x +pkg$images/t_laplace.x +pkg$images/t_gauss.x +pkg$images/t_convolve.x +pkg$images/convolve.x +pkg$images/xyconvolve.x +pkg$images/radcnv.x + The convolution operators were modified to run more efficiently in + certain cases. The LAPLACE task was modified to make use of the + radial symmetry of the convolution kernel in the y direction as well + as the x direction resulting in a modest speedup in execution time. + A new parameter bilinear was added to the GAUSS and CONVOLVE tasks. + By default and if appropriate mathematically, GAUSS now makes use of + the bilinearity or separability of the Gaussian function, + to separate the 2D convolution in x and y into two equivalent + 1D convolutions in x and y, resulting in a considerable speedup + in execution time. Similarly the user can know program CONVOLVE to + compute a bilinear convolution instead of a full 2D 1 if appropriate. + (1/29/91 Davis) + +pkg$images/filters/t_convolve.x + CONVOLVE was not decoding the legal 1D kernel "1.0 2.0 1.0" correctly + although the alternate form "1.0 2.0 1.0;" worked. Leading + blanks in string kernels as in for example " 1.0 2.0 1.0" also generated + and error. Fixed these bugs and added some additional error checking code. + (11/28/90 Davis) + +pkg$images/doc/gauss.hlp + Added a detailed mathematical description of the gaussian kernel used + by the GAUSS task to the help page. + +pkg$images/images.hd +pkg$images/rotate.cl +pkg$images/imlintran.cl +pkg$images/register.cl +pkg$images/register.par + Added src="script file name" entries to the IMAGES help database + for the tasks ROTATE, IMLINTRAN, and REGISTER. Changed the CL + script for REGISTER to a procedure script to remove the ugly + local variable declarations. Added a few comments to the scripts. + (12/11/90, Davis) + +pkg$images/iminfo/imhistogram.x + Added a new parameter binwidth to imhistogram. If binwidth is defined + it determines the histogram resolution in intensity units, otherwise + nbins determines the resolution as before. (10/26/90, Davis) + +pkg$images/doc/sections.hlp + Clarified what is meant by an image template and that the task itself + does not check whether the specified names are actually images. + The examples were improved. (10/3/90, Valdes) + +pkg$images/doc/fit1d.hlp + Changed lines to columns in example 2. (10/3/90, Valdes) + +pkg$images/imarith/imcscales.x + When an error occured while parsing the mode section the untrapped error + caused further problems downstream. Because it would require adding + lots of errchks to cause the program to gracefully abort I instead made + it a warning. (10/2/90, Valdes) + +pkg$images/imutil/hedit.x + Hedit was computing but not using min_lenarea. If the user specified + a min_lenuserarea greater than the default of 28800 then the default + was being used instead of the larger number. + +pkg$imarith/imasub.gx + The case of subtracting an image from the constant zero had a bug + which is now fixed. (8/14/90, Valdes) + +pkg$images/t_imtrans.x + Modified the imtranspose task so it will work on type ushort images. + (6/6/90 Davis) + +pkg$images + Added world coordinate system support to the following tasks: imshift, + shiftlines, magnify, imtranspose, blkrep, blkavg, rotate, imlintran, + register and geotran. The only limitation is that register and geotran + will only support simple linear transformations. + (2/24/90 Davis) + +pkg$images/geometry/geotimtran.x + Fixed a problem in the boundary extension "reflect" option code for small + images which was causing odd values to be inserted at the edges of the + image. + (2/14/90 Davis) + +pkg$images/iminfo/imhistogram.x + A new parameter "hist_type" was added to the imhistogram task giving + the user the option of plotting the integral, first derivative and + second derivative of the histogram as well as the normal histogram. + Code was contributed by Rob Seaman. + (2/2/90 Davis) + +pkg$images/geometry/geogmap.x + The path name of the help file was being erroneously renamed with + the result that when users ran the double precision version of the + code they could not find the help file. + (26/1/90 Davis) + +pkg$images/filters/t_boxcar.x,t_convolve.x + Added some checks for 1-D images. + (1/20/90 Davis) + +pkg$images/iminfo/t_imstat.x,imstat.h + Made several minor bug fixes and alterations in the imstatistics task + in response to user complaints and suggestions. + + 1. Changed the verbose parameter to the format parameter. If format is + "yes" (the default) then the selected fields are printed in fixed format + with column labels. Other wise the fields are printed in free format + separated by 2 blanks. This fixes the problem of fields running together. + + 2. Fixed a bug in the code which estimates the median from the image + histogram by linearly interpolating around the midpt of the integrated + histogram. The bug occurred when more than half the pixels were in the + first bin. + + 3. Added a check to ensure that the number of fields did not overflow + the fields array. + + 4. Removed the extraneous blank line printed after the title. + + 5. The pound sign is now printed at the beginning of the column header + string regardless of which field is printed first. In the previous + versions it was only being printed if the image name field was + printed first. + + 6. Changed the name of the median field to midpt in response to user + confusions about how the median is computed. + + (1/20/90, Davis) + +pkg$images/imutil/t_imslice.hlp + The imslice was not correctly computing the number of lines in the + output image in the case where the slice dimension was 1. + (12/4/89, Davis) + +pkg$images/doc/imcombine.hlp + Clarified and documented definitions of the scale, offset, and weights. + (11/30/89, Valdes) + +pkg$images/geometry/geotran.x + High order surfaces of a certain functional form could occasionally + produce out of bounds pixel errors. The bug was caused by not properly + computing the distortion of the image boundary for higher order + surfaces. + (11/21/89, Davis) + +pkg$images/geometry/imshift.x + The circulating buffer space was not being freed after each execution + of IMSHIFT. This did not cause an error in execution but for a long + list of frames could result in alot of memory being tied up. + (10/25/89, Davis) + +pkg$images/imarith/t_imarith.x + IMARITH is not prepared to deal with images sections in the output. + It used to look for '[' to decide if the output specification included + and image section. This has been changed to call the IMIO procedure + imgsection and check if a non-null section string is returned. + Thus it is up to IMIO to decide what part of the image name is + an image section. (9/5/89, Valdes) + +pkg$images/imarith/imcmode.gx + Fixed bug causing infinite loop when computing mode of constant value + section. (8/14/89, Valdes) + +==== +V2.8 +==== + +pkg$images/iminfo/t_imstat.x + Davis, Jun 15, 1989 + Added a couple of switches to that skew and kurtosis are not computed + if they are not to be printed. + +pkg$images/iminfo/t_imstat.x + Davis, Jun 14, 1989 + A simple mod was made to the skew and kurtosis computation to avoid + divide by zero errors in case of underflow. + +pkg$images/imutil/chpixtype.par + Davis, Jun 13, 1989 + The parameter file has been modified to accept an output pixel + type of ushort. + +pkg$images/imarith/imcombine.gx + Valdes, Jun 2, 1989 + A new scheme to detect file errors is now used. + +pkg$images/imfit/t_imsurfit.x + Davis, Jun 1, 1989 + 1. If the user set regions = "sections" but the sections file + did not exist the task would go into an infinite loop. The problem + was a missing error check on the open statement. + +pkg$images/iminfo/imhistogram.x,imhistogram.par + Davis, May 31, 1989 + A new version of imhistogram has been installed. These mods have + been made over a period of a month by Doug Tody and Rob Seaman. + The mods include + 1. An option to turn off log scaling of the y axis of the histogram plot. + 2. A new autoscale parameter which avoids aliasing problems for integer + data. + 3. A new parameter top_close which resolves the ambiguity in the top + bin of the histogram. + +pkg$images/imarith/imcombine.gx + Valdes, May 9, 1989 + Because a file descriptor was not reserved for string buffer operations + and a call to stropen in cnvdate was not error checked the task would + hang when more than 115 images were combined. Better error checking + was added and now an error message is printed when the maximum number + of images that can be combined is exceeded. + +pkg$images/imarith/t_imarith.x + Valdes, May 6, 1989 + Operations in which the output image has an image section are now + skipped with a warning message. + +pkg$images/imarith/sigma.gx +pkg$images/imarith/imcmode.gx + Valdes, May 6, 1989 + 1. The weighted sigma was being computed incorrectly. + 2. The argument declarations were wrong for integer input images. + Namely the mean vector is always real. + 3. Minor change to imcmode.gx to return correct datatype. + +pkg$images/imstack,imslice + Davis, April 1, 1989 + The proto images tasks imstack and imslice have been moved from the + proto package to the images package. Imstack is unchanged except that + it now supports the image data types USHORT and COMPLEX. Imslice has + been modified to allow slicing along any dimension of the image instead + of just the highest dimension. + +pkg$images/imstatistics. + Davis, Mar 31, 1989 + 1. A totally new version of the imstatistics task has been written + and replaces the old version. The new task allows the user to select + which statistical parameters to compute and print. These include + the mean, median, mode, standard deviation, skew, kurtosis and the + minimum and maximum pixel values. + +pkg$images/imhistogram.par +pkg$images/iminfo/imhistogram.x +pkg$images/doc/imhistogram.hlp + Davis, Mar 31, 1989 + 1. The imhistogram task has been modified to plot "box" style histograms + as well as "line" type histograms. Type "line" remains the default. + +pkg$images/geometry/geotran.par,register.par,geomap.par +pkg$images/doc/geomap.hlp,register.hlp,geotran.hlp + Davis, Mar 6, 1989 + 1. Improved the parameter prompting in GEOMAP, REGISTER and GEOTRAN + and improved the help pages. + 2. Changed GEOMAP database quantities "xscale" and "yscale" to "xmag" + and "ymag" for consistency . Geotran was changed appropriately. + +pkg$images/imarith/imcmode.gx + For short data a short variable was wraping around when there were + a significant number of saturated pixels leading to an infinite loop. + The variables were made real regardless of the image datatype. + (3/1/89, Valdes) + +pkg$images/imutil/imcopy.x + Davis, Feb 28, 1989 + 1. Added support for type USHORT to the imcopy task. This is a merged + ST modification. + +pkg$images/imarith/imcthreshold.gx +pkg$images/imcombine.par +pkg$images/doc/imcombine.hlp +pkg$images/imarith/imcscales.x + Valdes, Feb 16, 1989 + 1. Added provision for blank value when all pixels are rejected by the + threshold. + 2. Fixed a bug that was improperly scaling images in the threshold option. + 3. The offset printed in the log now has the opposite sign so that it + is the value "added" to bring images to a common level. + +pkg$images/imfit/imsurfit.x + Davis, Feb 23, 1989 + Fixed a bug in the median fitting code which could cause the porgram + to go into an infinite loop if the region to be fitted was less than + the size of the whole image. + +pkg$images/geometry/t_magnify.x + Davis, Feb 16, 1989 + Modified magnify to work on 1D images as well as 2D images. The + documentation has been updated. + +pkg$images/geometry/t_geotran.x + Davis, Feb 15, 1989 + Modified the GEOTRAN and REGISTER tasks so that they can handle a list + of transform records one for each input image. + +pkg$images/imarith/imcmode.gx + Valdes, Feb 8, 1989 + Added test for nx=1. + +pkg$images/imarith/t_imcombine.x + Valdes, Feb 3, 1989 + The test for the datatype of the output sigma image was wrong. + +pkg$images/iminfo/listpixels.x,listpixels.par + Davis, Feb 6, 1989 + The listpixels task has been modified to print out the pixels for a + list of images instead of a single image only. A title line for each + image listed can optionally be printed on the standard output if + the new parameter verbose is set to yes. + +pkg$images/geometry/t_imshift.x + Davis, Feb 2, 1989 + Added a new parameter shifts_file to the imshift task. Shifts_file + is the name of a text file containing the the x and yshifts for + each input image to be shifted. The number of input shifts must + equal the number of input images. + +pkg$images/geometry/t_geomap.x + Davis, Jan 17, 1989 + Added an error message for the case where the coordinates is empty + of there are no points in the specified data range. Previously the + task would proceed to the next coordinate file without any message. + +pkg$images/geometry/t_magnify.x + Davis, Jan 14, 1989 + Added the parameter flux conserve to the magnify task to bring it into + line with all the other geometric transformation tasks. + +pgk$images/geometry/geotran.x,geotimtran.x + Davis, Jan 2, 1989 + A bug was fixed in the flux conserve code. If the x and y reference + coordinates are not in pixel units and are not 1 then + the computed flux per pixel was too small by xscale * yscale. + +pkg$images/filters/acnvrr.x,convolve.x,boxcar.x,aboxcar.x + Davis, Dec 27, 1988 + I changed the name of the acnvrr procedure to cnv_radcnvr to avoid + a name conflict with a vops library procedure. This only showed + up when shared libraries were implemented. I also changed the name + of the aboxcarr procedure to cnv_aboxr to avoid conflict with the + vops naming conventions. + +pkg$images/imarith/imcaverage.gx + Davis, Dec 22, 1988 + Added an errchk statement for imc_scales and imgnl$t to stop the + program bombing with segmentation violations when mode <= 0. + +pkg$images/imarith/imcscales.x + Valdes, Dec 8, 1988 + 1. IMCOMBINE now prints the scale as a multiplicative quantity. + 2. The combined exposure time was not being scaled by the scaling + factors resulting in a final exposure time inconsistent with the + data. + +pkg$images/iminfo/imhistogram.x + Davis, Nov 30, 1988 + Changed the list+ mode so that bin value and count are printed out instead + of bin count and value. This makes the plot and list modes compatable. + +pkg$images/iminfo/t_imstat.x + Davis, Nov 17, 1988 + Added the n=n+1 back into the inner loop of imstat. + +pkg$images/geotran.par,register.par + Davis, Nov 11 , 1988 + Fixed to glaring errors in the parameter files for register and geotran. + Xscale and yscale were described as pixels per reference unit when + they should be reference units per pixel. The appropriate bug fix has been + made. + +pkg$images/geometry/t_geotran.x + Davis, November 7, 1988 + The routine gsrestore was not being error checked. If either of the + input x or y coordinate surface was linear and the other was not, + the message came back GSRESTORE: Illegal x coordinate. This bug has + been fixed. + +pkg$images/imarith/imcombine.gx + Valdes, October 19, 1988 + A vops clear routine was not called generically causing a crash with + double images. + +pkg$images/filters/t_fmedian.x,t_median.x,t_fmode.x,t_mode.x,t_gradient.x + t_gauss.x,t_boxcar.x,t_convolve.x,t_laplace.x + Davis, October 4, 1988 + I fixed a bug in the error handling code for the filters tasks. If + and error occurred during task execution and the input image name was + the same as the output image name then the input image was trashed. + +pkg$images/imarith/imcscales.gx + Valdes, September 28, 1988 + It is now an error for the mode to be nonpositive when scaling or weighting. + +pkg$images/imarith/imcmedian.gx + Valdes, August 16, 1988 + The median option was selecting the n/2 value instead of (n+1)/2. Thus, + for an odd number of images the wrong value was being determined for the + median. + +pkg$images/geometry/t_imshift.x + Davis, August 11, 1988 + 1. Imshift has been modified to uses the optimized code if nearest + neighbour interpolation is requested. A nint is done on the shifts + before calling the quick shift routine. + 2. If the requested pixel shift is too large imshift will now + clean up any pixelless header files before continuing execution. + +pkg$images/geometry/blkavg.gx + Davis, July 13, 1988 + Blkavg has been fixed so that it will work on 1D images. + +pkg$images/geometry/t_imtrans.x,imtrans.x + Davis, July 12, 1988 + Imtranspose has been modified to work on complex images. + +pkg$images/imutil/t_chpix.x + Davis, June 29, 1988 + A new task chpixtype has been added to the images package. Chpixtype + changes the pixel types of a list of images to a specified output pixel + type. Seven data types are supported "short", "ushort", "int", "long" + "real" and "double". + +pkg$images/geometry/rotate.cl,imlintran.cl,t_geotran.x + Davis, June 10, 1988 + The rotate and imlintran scripts have been rewritten to use procedure + scripts. This removes all the annoying temporary cl variables which + appear when the user does an lpar. In previous versions of these + two tasks the output was restricted to being the same size as the input + image. This is still the default case, but the user can now set the + ncols and nrows parameters to the desired output size. I ncols or nlines + < 0 then then the task compute the output image size required to contain + the whole input image. + +pkg$images/filters/t_convolve.x,t_laplace.x,t_gradient.x,t_gauss.x,convolve.x + Davis, June 1, 1988 + The convolution operators laplace, gauss and convolve have been modified + to make use of radial symmetry in the convolution kernel. In gauss and + laplace the change is transparent to the user. For the convolve operator + the user must indicate that the kernel is radially symmetric by setting + the parameter radsym. For kernels of 7 by 7 or greater the speedup + in timings is on the order of 30% on the Vax 750 with the fpa. + +pkg$images/imarith/imcmode.gx + Valdes, Apr 11, 1988 + 1. The use of a mode sections was handled incorrectly. + +pkg$images/imfit/fit1d.x + Valdes, Jan 4, 1988 + 1. Added an error check for a failure in IMMAP. The missing error check + caused FIT1D to hang when a bad input image was specified. + +pkg$images/magnify.par +pkg$images/imcombine.par +pkg$images/imarith/imcmode.gx +pkg$images/doc/imarith.hlp + Valdes, Dec 7, 1987 + 1. Added option list to parameter prompts. + 2. Fixed minor typo in help page + 3. The mode calculation in IMCOMBINE would go into an infinite loop + if all the pixel values were the same. If all the pixels are the + same them it skips searching for the mode and returns the constant + number. + +pkg$images/geometry/geotimtran.x + Davis, Nov 25, 1987 + 1. A bug in the boundary extension = wrap option was found in the + IMLINTRAN task. The problem occured in computing values for out of + bounds pixels in the range 0.0 < x < 1.0, ncols < x < ncols + 1.0, + 0.0 < y < 1.0 and nlines < y < nlines + 1. The computed coordinates + were falling outside the boundaries of the interpolation array. + +pkg$images/geometry/t_geomap.x,geograph.x + Davis, Nov 19, 1987 + 1. The geomap task now writes the name of the output file into the database. + 2. Rotation angles of 360. degrees have been altered to 0 degrees. + +pkg$images/imfit/t_imsurfit.x,imsurfit.x +pkg$images/lib/ranges.x + Davis, Nov 2, 1987 + A bug in the regions fitting option of the IMSURFIT task has been found + and fixed. This bug would occur when the user set the regions parameter + to sections and then listed section which overlapped each other. The + modified ranges package was not handling the overlap correctly and + computing a number of points which was incorrect. + +pkg$images/imarith/* + + Valdes, Sep 30, 1987 + The directory was reorganized to put generic code in the subdirectory + generic. + + A new task called IMCOMBINE has been added. It provides for combining + images by a number of algorithms, statistically weighting the images + when averaging, scaling or offsetting the images by the exposure time + or image mode before combining, and rejecting deviant pixels. It is + almost fully generic including complex images and works on images of + any dimension. + +pkg$images/geometry/geotran.x + Davis, Sept 3, 1987 + A bug in the flux conserving algorithm was found in the geotran code. + The symptom was that the flux of the output image occasionally was + negative. This would happen when two conditions were met, the transformation + was of higher order than a simple rotation, magnification, translation + and an axis flip was involved. The mathematical interpretation of this + bug is that the coordinate surface had turned upside down. The solution + for people running systems with this bug is to multiply there images + by -1. + +pkg$images/imfit/imsurfit.h,t_imsurfit.x + Davis, Aug 6, 1987 + A new option was added to the parameter regions in the imsurfit task. + Imsurfit will now fit a surface to a single circular region defined + by an x and y center and a radius. + +pkg$images/geometry/geotimtran.x + Davis, Jun 15, 1987 + Geotran and register were failing when the output image number of rows + and columns was different from the input number of rows and columns. + Geotran was mistakenly using the input images sizes to determine the + number of output lines that should be produced. The same problem occurred + when the values of the boundary pixels were being computed. The program + was using the output image dimensions to compute the boundary pixels + instead of the input image dimensions. + +pkg$images/geometry/geofit.x,geogmap.x + Davis, Jun 11, 1987 + A bug in the error checking code in the geomap task was fixed. The + condition of too few points for a reasonable was not being trapped + correctly. The appropriate errchk statements were added. + +pkg$images/geomap.par + Davis, Jun 10, 1987 + The default fitting function was changed to polynomial. This will satisfy + most users who wish to do shifts, rotations, and magnifications and + avoid the neccessity of correctly setting the xmin, xmax, ymin, and ymax + parameters. For the chebyshev and legendre polynomial functions these + parameters must be explicitly set. For reference coordinates in pixel + units the normal settings are 1, ncols, 1 and nlines respectively. + +pkg$images/iminfo/hselect.x,imheader.x,images$/imutil/hselect.x + Davis, Jun 8, 1987 + Imheader has been modified to open an image with the default min_lenuserarea + Hselect and hedit will now open the image setting the user area to the + maximum of 28800 chars or the min_lenuser environment variable. + +pkg$images/iminfo/t_imstat.x + Davis, May 22, 1987 + An error in the image minimum computation was corrected. This error + would show up most noiticeably if imstat was run on a 1 pixel image. + The min value would be left set to MAX_REAL. + +pkg$images/filters/mkpkg + Davis, May 22, 1987 + I added mach.h to the dependency file list of t_fmedian.x and + recompiled. The segmentation violations I had been getting in the + program disappeared. + +pkg$images/t_shiftlines.x,shiftlines.x + Davis, April 15, 1987 + 1. I changed the names of the procedures shiftlines and shiftlinesi + to sh_lines and sh_linesi. When the original names were contracted + to 6 letter fortran names they became shifti and shifts which just + so happens to collide with shifti and shifts in the subdirectory + osb. On VMS this was causing problems with the shareable libraries. + If images was linked with -z there was no problem. + +pkg$images/imarith/t_imsum.x + Valdes, March 24, 1987 + 1. IMSUM was failing to unmap images opened to check image dimensions + in a quick first pass through the image list. This is probably + the source of the out of files problem with STF images. It may + be the source of the out of memory problem reported from AOS/IRAF. + +pkg$images/imfit/fit1d.x +pkg$images/imfit/mkpkg + Valdes, March 17, 1987 + 1. Added error checking for the illegal operation in which both input + and output image had an image section. This was causing the task + to crash. The task now behaves properly in this circumstance and + even allows the fitted output to be placed in an image section of + an existing output image (even different than the input image + section) provided the input and output images have the same sizes. + +pkg$images/t_convolve.x + Davis, March 3, 1987 + 1. Fixed the kernel decoding routine in the convolve task so that + it now recognizes the row delimter character in string entry mode. + +pkg$images/geometry,filters + Davis, February 27, 1987 + 1. Changed all the imseti (im, TY_BNDRYPIXVAL, value) calls to imsetr. + +pkg$images/t_minmax.x,minmax.x + Davis, February 24, 1987 + 1. Minmax has been changed to compute the minimum and maximum pixel + as well as the minimum and maximum pixel values. The pixels are output + in section notation and stored in the minmax parameter file. + +pkg$images/t_magnify.x + Davis, February 19, 1987 + 1. Magnify was aborting with the error MSIFIT: Too few datapoints + when trying to reduce an image using the higher order interpolants + poly3, poly5 and spline3. I increased the NEDGE defined constant + from 2 to three and modified the code to use the out of bounds + imio. + +pkg$images/geograph.x,geogmap.x + Davis, February 17, 1987 + 1. Geomap now uses the gpagefile routine to page the .keys file. + The :show command deactivates the workstation before printing a + block of text and reactivates it when it is finished. + +pkg$images/geometry/geomap,geotran + Davis, January 26, 1987 + 1. There have been substantial changes to the geomap, and geotrans + tasks and those tasks rotate, imlintran and register which depend + on them. + 2. Geomap has been changed to be able to compute a transformation + in both single and double precision. + 3. The geotran code has been speeded up considerably. A simple rotate + now takes 70 seconds instead of 155 seconds using bilinear interpolation. + 4. Two new cl parameters nxblock and nyblock have been added to the + rotate, imlintran, register and geotran tasks. If the output image + is smaller than these parameters then the entire output image + is computed at once. Otherwise the output image is computed in blocks + nxblock by nyblock in size. + 5. The 3 geotran parameters rotation, scangle and flip have been replaced + with two parameters xrotation and yrotation which serve the same purpose. + +pkg$images/geometry/t_shiftlines.x,shiftlines.x + Davis, January 19, 1987 + 1. The shiftlines task has been completely rewritten. The following + are the major changes. + 2. Shiftlines now makes use of the imio boundary extension operations. + Therefore the four options: nearest pixel, reflect, wrap and constant + boundary extension are available. + 3. The interpolation code has been vectorised. The previous version + was using the function call asieval for every output pixel evaluated. + The asieval call were replaced with asivector calls. + 4. An extra CL parameter constant to support constant boundary + exension was added. + 5. The shiftlines help page was modified and the date changed to + January 1987. + +pkg$images/imfit/imsurfit.x + Davis, January 12, 1987 + 1. I changed the amedr call to asokr calls. For my application it did + not matter whether the input array is left partially sorted and the asokr + routine is more efficient. + +pkg$images/lib/pixlist.x + Davis, December 12, 1986 + 1. A bug in the pl_get_ranges routine caused the routine to fail when the + number of ranges got too large. The program could not detect the end of + the ranges and would go into an infinite loop. + +pkg$images/iminfo/t_imstat.x + Davis, December 3, 1986 + 1. Imstat was failing on constant images because finite machine precision + could result in a negative sigma squared. Added a check for this condition. + +pkg$images/filters/fmode.x + Davis, October 27, 1986 + 1. Added a check for 0 data range before calling amapr. + +pkg$images/imarith/imsum.gx + Valdes, October 20, 1986 + 1. Found and fixed bug in this routine which caused pixel rejection + to fail some fraction of the time. + +pkg$images/geometry/blkrp.gx + Valdes, October 13, 1986 + 1. There was a bug when the replication factor for axis 1 was 1. + +pkg$images/iminfo/imhistogram.x + Hammond, October 8, 1986 + 1. Running imhistogram on a constant valued image would result in + a "floating divide by zero fault" in ahgm. This condition is + now trapped and a warning printed if there is no range in the data. + +pkg$images/tv/doc/cvl.hlp + Valdes, October 7, 1986 + 1. Typo in V2.3 documentation fixed: "zcale" -> "zscale". + +pkg$images/fit1d.par + Valdes, October 7, 1986 + 1. When querying for the output type the query was: + +Type of output (fit, difference, ratio) (fit|difference|ratio) (): + + The enumerated values were removed since they are given in the + prompt string. + +pkg$images/imarith/t_imsum.x +pkg$images/imarith/imsum.gx +pkg$images/do/imsum.hlp + Valdes, October 7, 1986 + 1. Medians or pixel rejection with more than 15 images is now + correct. There was an error in buffering. + 2. Averages of integer datatype images are now correct. The error + was caused by summing the pixel values divided by the number + of images instead of summing the pixel values and then dividing + by the number of images. + 3. Option keywords may now be abbreviated. + 4. The output pixel datatype now defaults to the calculation datatype + as is done in IMARITH. The help page was modified to indicate this. + 5. Dynamic memory is now used throughout to reduce the size of the + executable. + 6. The bugs 1-2 are present in V2.3 and not in V2.2. + +pkg$images/imarith/t_imarith.x +pkg$images/imarith.par +pkg$images/doc/imarith.hlp + Valdes, October 6, 1986 + 1. The parameter "debug" was changed to "noact". "debug" is reserved + for debugging information. + 2. The output pixel type now defaults to the calculation datatype. + 3. The datatype of constant operands is determined with LEXNUM. This + fixes a bug in which a constant such as "1." was classified as an + integer. + 4. Trailing whitespace in the string for a constant operand is allowed. + This fixes a bug with using "@" files created with the task FIELDS + from a table of numbers. Trailing whitespace in image names is + not checked for since this should be taken care of by lower level + system services. + 5. The reported bug with the "max" operation not creating a pixel file + was the result of the previous round of changes. This has been + corrected. This problem does not exist in the released version. + 6. All strings are now dynamically allocated. Also IMTOPENP is used + to open a CL list directly. + 7. The help page was revised for points (1) and (2). + +pkg$images/fmode.par +pkg$images/fmd_buf.x +pkg$images/med_sort.x + Davis, September 29, 1986 + 1. Changed the default value of the unmap parameter in fmode to yes. The + documentation was changed and the date modified. + 2. Added a test to make sure that the input image was not a constant + image in fmode and fmedian. + 3. Fixed the recently added swap macro in the sort routines which + was giving erroneous results for small boxes in tasks median and mode. + +pkg$images/imfit/fit1d.x + Valdes, September 24, 1986 + 1. Changed subroutine name with a VOPS prefix to one with a FIT1D + prefix. + +pkg$images/imarith/t_imdivide.x +pkg$images/doc/imdivide.hlp +pkg$images/imdivide.par + Valdes, September 24, 1986 + 1. Modified this ancient and obsolete task to remove redundant + subroutines now available in the VOPS library. + 2. The option to select action on zero divide was removed since + there was only one option. Parameter file changed. + 3. Help page revised. + +pkg$images/geometry/t_blkrep.x + +pkg$images/geometry/blkrp.gx + +pkg$images/geometry/blkrep.x + +pkg$images/doc/blkrep.hlp + +pkg$images/doc/mkpkg +pkg$images/images.cl +pkg$images/images.men +pkg$images/images.hd +pkg$images/x_images.x + Valdes, September 24, 1986 + 1. A new task called BLKREP for block replicating images has been added. + This task is a complement to BLKAVG and performs a function not + available in any other way. + 2. Help for BLKREP has been added. + +pkg$images/imarith/t_imarith.x +pkg$images/imarith/imadiv.gx +pkg$images/doc/imarith.hlp +pkg$images/imarith.par + Valdes, September 24, 1986 + 1. IMARITH has been modified to provide replacement of divisions + by zero with a constant parameter value. + 2. The documentation has been revised to include this change and to + clarify and emphasize areas of possible confusion. + +pkg$images/doc/magnify.hlp +pkg$images/doc/blkavg.hlp + Valdes, September 18, 1986 + 1. The MAGNIFY help document was expanded to clarify that images with axis + lengths of 1 cannot be magnified. Also a discussion of the output + size of a magnified image. This has been misunderstood often. + 2. Minor typo fix for BLKAVG. + +images$geometry/blkav.gx: Davis, September 7, 1986 + 1. The routine blkav$t was declared a function but called everywhere as + a procedure. Removed the function declaration. + +images$filters/med_sort.x: Davis, August 14, 1986 + 1. A bug in the sorting routine for MEDIAN and MODE in which the doop + loop increment was being set to zero has been fixed. This bug was + causing MEDIAN and MODE to fail on class 6 for certain sized windows. + +images$imfit/fit1d.x: Davis, July 24, 1986 + 1. A bug in the type=ratio option of fit1d was fixed. The iferr call + on the vector operator adivr was not trapping a divide by zero + condition. Changed adivr to adivzr. + +images$iminfo/listpixels.x: Davis, July 21, 1986 + 1. I changed a pargl to pargi for writing out the column number of the + pixels. + +images$iminfo/t_imstat.x: Davis, July 21, 1986 + 1. I changed a pargr to a pargd for the double precision quantitiies + sum(MIN) and sum(MAX). + +images$imfit/t_lineclean.x: Davis, July 14, 1986 + 1. Bug in the calling sequence for ic_clean fixed. The ic pointer + was not being passed to ic_clean causing access violation and/or + segmentation violation errors. + +images$imfit/fit1d.x, lineclean.x: Valdes, July 3, 1986 + 1. FIT1D and LINECLEAN modified to use new ICFIT package. + +From Valdes June 19, 1986 + +1. The help page for IMSUM was modified to explicitly state what the +median of an even number of images does. + +----------------------------------------------------------------------------- + +From Davis June 13, 1986 + +1. A bug in CONVOLVE in which insufficient space was being allocated for +long (> 161 elements) 1D kernels has been fixed. CONVOLVE was not +allocating sufficent extra space. + +----------------------------------------------------------------------------- + +From Davis June 12, 1986 + +1. I have changed the default value of parameter unmap in task FMEDIAN to +yes to preserve the original data range. + +2. I have changed the value of parameter row_delimiter from \n to ;. + +----------------------------------------------------------------------------- + +From Davis May 12, 1986 + +1. Changed the angle convention in GAUSS so that theta is the angle of the +major axis with respect to the x axis measured counter-clockwise as specified +in the help page instead of the negative of that angle. + +----------------------------------------------------------------------------- + +From Davis Apr 28, 1986 + +1. Moved geomap.key to lib$scr and made redefined HELPFILE in geogmap.x +appropriately. + +------------------------------------------------------------------------------ + +images$imarith/imsum.gx: Valdes Apr 25, 1986 + 1. Fixed bug in generic code which called the real VOPS operator + regardless of the datatype. This caused IMSUM to fail on short + images. + +From Davis Apr 17, 1986 + +1. Changed constructs of the form boolean == false in the file imdelete.x +to ! boolean. + +------------------------------------------------------------------------------ + +images$imarith: Valdes, April 8, 1986 + 1. IMARITH has been modified to also operate on a list of specified + header parameters. This is primarily used when adding images to + also added the exposure times. A new parameter was added and the + help page modified. + 2. IMSUM has been modified to also operate on a list of specified + header parameters. This is primarily used when summing images to + also sum the exposure times. A new parameter was added and the + help page modified. + +------------------------------------------------------------------------------ + +From Valdes Mar 24, 1986: + +1. When modifying IMARITH to handle mixed dimensions the output image header +was made a copy of the image with the higher dimension. However, the default +when the images were of the same dimension changed to be a copy of the second +operand. This has been changed back to being a copy of the first operand +image. + +------------------------------------------------------------------------------ + +From Davis Mar 21, 1986: + +1. A NULL pointer bug in the subroutine plfree inside IMSURFIT was causing +segmentation violation errors. A null pointer test was added to plfree. + +------------------------------------------------------------------------------ + +From Davis Mar 20, 1986: + +1. A bug involving in place operations in several image tasks has been fixed. + +------------------------------------------------------------------------------ + +From Davis Mar 19, 1986: + +1. IMSURFIT no longer permits the input image to be replaced by the output +image. + +2. The tasks IMSHIFT, IMTRANSPOSE, SHIFTLINES, and GEOTRAN have been modified +to use the images tools xt_mkimtemp and xt_delimtemp for in place +calculations. + +------------------------------------------------------------------------------- + +From Valdes Mar 13, 1986: + +1. Bug dealing with type coercion in short datatype images in IMARITH and IMSUM +which occurs on the SUN has been fixed. +------ +From Valdes Mar 10, 1986: + +1. IMSUM has been modified to work on any number of images. + +2. Modified the help page +------ +From Valdes Feb 25, 1986: + +There have been two changes to IMARITH: + +1. A bug preventing use of image sections has been removed. + +2. An improvement allowing use of images of different dimension. +The algorithm is as follow: + + a. Check if both operands are images. If not the output + image is a copy of the operand image. + + b. Check that the axes lengths are the same for the dimensions + in common. For example a 3D and 2D image must have the same + number of columns and lines. + + c. Set the output image to be a copy of the image with the + higher dimension. + + d. Repeat the operation over the lower dimensions for each of + the higher dimensions. + +For example, consider subtracting a 2D image from a 3D image. The output +image will be 3D and the 2D image is subtracted from each band of the +3D image. This will work for any combination of dimensions. Another +example is dividing a 3D image by a 1D image. Then each line of each +plane and each band will be divided by the 1D image. Likely applications +will be subtracting biases and darks and dividing by response calibrations +in stacked observations. + +3. Modified the help page +=========== +Release 2.2 +=========== +From Davis Mar 6, 1986: + +1. A serious bug had crept into GAUSS after I made some changes. For 2D +images the sense of the sigma was reversed, i.e sigma = 2.0 was actually +sigma = 0.5. This bug has now been fixed. + +--------------------------------------------------------------------------- + +From Davis Jan 13, 1986: + +1. Listpixels will now print out complex pixel values correctly. + +--------------------------------------------------------------------------- + +From Davis Dec 12, 1985: + +1. The directional gradient operator has been added to the images package. + +--------------------------------------------------------------------------- + +From Valdes Dec 11, 1985: + +1. IMARITH has been modified to first check if an operand is an existing +file. This allows purely numeric image names to be used. + +--------------------------------------------------------------------------- + +From Davis Dec 11, 1985: + +1. A Laplacian (second derivatives) operator has been added to the images +package. + +--------------------------------------------------------------------------- + +From Davis Dec 10, 1985: + +1. The new convolution tasks boxcar, gauss and convolve have been added +to the images package. Convolve convolves an image with an arbitrary +user supplied rectangular kernel. Gauss convolves an image with a 2D +Gaussian of arbitrary size. Boxcar will smooth an image using a smoothing +window of arbitrary size. + +2. The images package source code has been reorganized into the following +subdirectories: 1) filters 2) geometry 3) imfit 4) imarith 4) iminfo and +5) imutil 6) lib. Lib contains routines which may be of use to several IRAF +tasks such as ranges. The imutil subdirectory contains tasks which modify +images in some way such as hedit. The iminfo subdirectory contains code +for displaying header and pixel values and other image characteristics +such as the histogram. Image arithmetic and fitting routines are found +in imarith and imfit respectively. Filters contains the convolution and +median filtering routines and geometry contains the geometric distortion +corrections routines. + +3. The documentation of the main images package has been brought into +conformity with the new IRAF standards. + +4. Documentation for imdelete, imheader, imhistogram, listpixels and +sections has been added to the help database. + +5. The parameter structure for imhistogram has been simplified. The +redundant parameters sections and setranges have been removed. + +--------------------------------------------------------------------------- + + +From Valdes Nov 4, 1985: + +1. IMCOPY modified so that the output image may be a directory. Previously +logical directories were not correctly identified. +------ + +From Davis Oct 21, 1985: + +1. A bug in the pixel rejection cycle of IMSURFIT was corrected. The routine +make_ranges in ranges.x was not successfully converting a sorted list of +rejected pixels into a list of ranges in all cases. + +2. Automatic zero divide error checking has been added to IMSURFIT. +------ +From Valdes Oct 17, 1985: + +1. Fit1d now allows averaging of image lines or columns when interactively +setting the fitting parameters. The syntax is "Fit line = 10 30"; i.e. +blank separated line or column numbers. A single number selects just one +line or column. Be aware however, that the actual fitting of the image +is still done on each column or line individually. + +2. The zero line in the interactive curve fitting graphs has been removed. +This zero line interfered with fitting data near zero. +------ +From Rooke Oct 10, 1985: + +1. Blkaverage was changed to "blkavg" and modified to support any allowed +number of dimensions. It was also made faster in most cases, depending on +the blocking factors in each dimension. +------ +From Valdes Oct 4, 1985: + +1. Fit1d and lineclean modified to allow separate low and high rejection +limits and rejection iterations. +------ +From Davis Oct 3, 1985: + +1. Minmax was not calculating the minimum correctly for integer images. +because the initial values were not being set correctly. +------ +From Valdes Oct 1, 1985: + +1. Imheader was modified to print the image history. Though the history +mechanism is little used at the moment it should become an important part +of any image. + +2. Task revisions renamed to revs. +------ +From Davis Sept 30, 1985: + +1. Two new tasks median and fmedian have been added to the images package. +Fmedian is a fast median filtering algorithm for integer data which uses +the histogram of the image to calculate the median at each window. Median +is a slower but more general algorithm which performs the same task. +------ +From Valdes August 26, 1985: + +1. Blkaverage has been modified to include an new parameter called option. +The current options are to average the blocks or sum the blocks. +------ +From Valdes August 7, 1985 + +1. Fit1d and lineclean wer recompiled with the modified icfit package. +The new package contains better labeling and graph documentation. + +2. The two tasks now have parameters for setting the graphics device +and reading cursor input from a file. +______ +From: /u2/davis/ Tue 08:27:09 06-Aug-85 +Package: images +Title: imshift bug + +Imshift was shifting incorrectly when an integral pixel shift in x and +a fractional pixel shift in y was requested. The actual x shift was +xshift + 1. The bug has been fixed and imshift will now work correctly for +any combination of fractional and integral pixel shifts +------ +From: /u2/davis/ Fri 18:14:12 02-Aug-85 +Package: images +Title: new images task + +A new task GEOMAP has been added to the images package. GEOMAP calculates +the spatial transformation required to map one image onto another. +------ +From: /u2/davis/ Thu 16:47:49 01-Aug-85 +Package: images +Title: new images tasks + +The tasks ROTATE, IMLINTRAN and GEODISTRAN have been added to the images +package. ROTATE rotates and shifts an image. IMLINTRAN will rotate, rescale +and shift an an image. GEODISTRAN corrects an image for geometric distortion. +------ +From Valdes July 26, 1985: + +1. The task revisions has been added to page revisions to the images +package. The intent is that each package will have a revisions task. +Note that this means there may be multiple tasks named revisions loaded +at one time. Typing revisions alone will give the revisions for the +current package. To get the system revisions type system.revisions. + +2. A new task called fit1d replaces linefit. It is essentially the same +as linefit except for an extra parameter "axis" which selects the axis along +which the functions are to be fit. Axis 1 is lines and axis 2 is columns. +The advantages of this change are: + + a. Column fitting can now be done without transposing the image. + This allows linefit to be used with image sections along + both axes. + b. For 1D images there is no prompt for the line number. +.endhelp diff --git a/pkg/images/imfit/doc/fit1d.hlp b/pkg/images/imfit/doc/fit1d.hlp new file mode 100644 index 00000000..5b49f45f --- /dev/null +++ b/pkg/images/imfit/doc/fit1d.hlp @@ -0,0 +1,177 @@ +.help fit1d Jul85 images.imfit +.ih +NAME +fit1d -- fit a function to image lines +.ih +USAGE +.nf +fit1d input output type +.fi +.ih +PARAMETERS +.ls input +Images to be fit. The images may contain image sections. Only the region +covered by the section will be modified in the output image. +.le +.ls output +Output images to be created or modified. The number of output images +must match the number of input images. If an output image does not exist +it is first created and initialized to zero for fit types "fit" and +"difference" and to one for fit type "ratio". +.le +.ls type +Type of output. The choices are: +.ls fit +An image created from the function fits to the image lines. +.le +.ls difference +The difference between the image and the fit (i.e. residuals). +.le +.ls ratio +The ratio of the image and fit. +.le +.le +.ls bpm = "" +List of bad pixel masks. This may be a null string to not use a +bad pixel mask, a single mask that applies to all input images, or +a matching list. The value may also be !<keyword> to specify a keyword whose +value is the mask to use. +.le +.ls axis = 1 +Axis along which the one dimensional fitting is done. Axis 1 corresponds +to fitting the image lines and axis 2 corresponds to fitting the columns. +.le +.ls interactive = yes +If \fBinteractive\fR is set to yes, a plot of the fit is drawn and the +cursor is available for interactively examining and adjusting the fit. +.le +.ls sample = "*" +Lines or columns to be used in the fits. +.le +.ls naverage = 1 +Number of sample points to combined to create a fitting point. +A positive value specifies an average and a negative value specifies +a median. +.le +.ls function = spline3 +Function to be fit to the image lines or columns. The functions are +"legendre" (legendre polynomial), "chebyshev" (chebyshev polynomial), +"spline1" (linear spline), and "spline3" (cubic spline). The functions +may be abbreviated. +.le +.ls order = 1 +The order of the polynomials or the number of spline pieces. +.le +.ls low_reject = 0., high_reject = 0. +Rejection limits below and above the fit in units of the residual sigma. +.le +.ls niterate = 1 +Number of rejection iterations. +.le +.ls grow = 0. +When a pixel is rejected, pixels within this distance of the rejected pixel +are also rejected. +.le +.ls graphics = "stdgraph" +Graphics output device for interactive graphics. +.le +.ls cursor = "stdgcur" +Graphics cursor input. +.le +.ih +DESCRIPTION +A one dimensional function is fit to each line or column of the input images. +The function may be a legendre polynomial, chebyshev polynomial, +linear spline, or cubic spline of a given order or number of spline pieces. +The output image is of pixel type real and is formed from the fitted +function values, the difference or residuals of the fit (pixel value - +fitted value), or the ratio between the pixel values and the fitted values. + +The output image may exist in which case a section in the input image is +applied to the output image. Thus, a section on the input image causes only +that part of the output image to be changed. If the output image does not +exist it is first created with a size given by the full (without a section) +input image and initialized to zero for fit and difference output types +and one for ratio output types. + +A bad pixel mask may be specified to exclude data from the fitting. Any +non-zero value in the mask is excluded. It appears in the interactive +fitting in the same way as manually deleted points. The mask is matched to +the input image(s) as described by \fBpmmatch\fR. The default is matching +in physical coordinates. + +The points fit are determined by selecting a sample of lines or columns +specified by the parameter \fIsample\fR and taking either the average or +median of the number of points specified by the parameter \fInaverage\fR. +The type of averaging is selected by the sign of the parameter and the number +of points is selected by the absolute value of the parameter. +The sample points are specified relative to any image sections. + +If \fIlow_reject\fR and/or \fIhigh_reject\fR are greater than zero the sigma +of the residuals between the fitted points and the fitted function is computed +and those points whose residuals are less than \fI-low_reject\fR * sigma +and greater than \fIhigh_reject\fR * sigma are excluded from the fit. +Points within a distance of \fIgrow\fR pixels of a rejected pixel are also +excluded from the fit. The function is then refit without the rejected points. +This rejection procedure may be iterated a number of times given by the +parameter \fIniterate\fR. + +The fitting parameters (\fIsample, naverage, function, order, low_reject, +high_reject, niterate, grow\fR) +may be adjusted interactively if the parameter \fIinteractive\fR is yes. +Lines or columns from the image are selected to be fit with the \fBicfit\fR +package. A single column or line may be chosen or a blank-separated range +may be averaged. Note that the averaging applies only to the graphed +data used to set the fitting parameters. The actual image lines and columns +are fit individually. The interactive cursor mode commands for this package +are described in a separate help entry under "icfit". Line 1 is automatically +selected for one dimensional images and any number of lines or columns may be +selected for two dimensional images. Note that the lines or columns are +relative to the input image section; for example line 1 is the first line of +the image section and not the first line of the image. When an end-of-file or +no line(s) or column(s) are given then the last selected fitting parameters +are used on each line or column of the image. This step is repeated for +each image in the input list. +.ih +EXAMPLES +1. To create a smoothed version of an image by fitting the image lines: + + cl> fit1d image fitimage fit + +If the interactive flag is set and the image is two dimensional then a prompt +for an image line is printed: + + image: Fit line = 100 200 + +The selected lines are averaged, graphed, and the interactive options for +setting and fitting the line are used. Exiting with 'q' or return prompts for +another line if the image is two dimensional. When the fitting parameters +are suitably set then respond with end-of-file or return to fit all the lines +of the image and create the output image. + +2. To subtract a linear function fit to columns 10 to 20 and 80 to 100 from +columns 10 to 100 and to subtract another linear function fit to lines +110 to 120 and 180 to 200 from columns 110 to 200: + +.nf + cl> fit1d image1[10:100,*] output diff axis=2 sample="1:11,71:91" + cl> fit1d image1[110:200,*] output diff axis=2 sample="1:11,71:91" +.fi + +Pixels outside columns 10 to 100 and 110 to 200 are not affected. Note that the +sample points are specified relative to the image sections. The script +\fBbackground\fR is available in other packages for doing background +subtractions. + +3. To determine a small scale response image: + + cl> fit1d image1 flat ratio + +The task \fBimred.generic.flat1d\fR is available for making flat field images +by this method with the addition of an extra parameter to limit the data values +for which the ratio is computed. +.ih +SEE ALSO +imred.generic.background, imred.generic.flat1d +xtools.icfit, lineclean, imsurfit +.endhelp diff --git a/pkg/images/imfit/doc/imsurfit.hlp b/pkg/images/imfit/doc/imsurfit.hlp new file mode 100644 index 00000000..0aa46a97 --- /dev/null +++ b/pkg/images/imfit/doc/imsurfit.hlp @@ -0,0 +1,226 @@ +.help imsurfit Feb88 images.imfit +.ih +NAME +imsurfit -- fit a surface function to an image +.ih +USAGE +imsurfit input, output, xorder, yorder +.ih +PARAMETERS +.ls input +List of images to be fit. +.le +.ls output +Output image(s) of \fItype_output\fR. +.le +.ls xorder +The order in x of the polynomials (1 = constant) or the number of polynomial +pieces for the bicubic spline. +.le +.ls yorder +The order in y of the polynomials (1 = constant) or the number of polynomial +pieces for the bicubic spline. +.le +.ls cross_terms = yes +Cross terms for the polynomials. For example, if \fIxorder\fR = 2 and +\fIyorder\fR = 2 +then a function of the form z = a + b * x + c * y + d * x * y will be fit. +.le +.ls function = "leg" +Functional for of surface to be fit to the image. The available functions +(with minimum match abbreviation) are: +.ls legendre +.le +.ls chebyshev +.le +.ls spline3 +.le +.ls spline1 +.le +.le +.ls type_output = "fit" +The type of output image. The allowed types (with minimum match abbreviation) +are: +.ls clean +The input image with deviant pixels in the good regions replaced by the +fitted value. +.le +.ls fit +An image created from the surface fits to the image. +.le +.ls residual +The difference of the input image and the fitted image. +.le +.ls response +The ratio of the input image to the fitted image. +All fitted (denominator) pixels below \fIdiv_min\fR are given a value of 1. +.le +.le +.ls xmedian = 1, ymedian = 1 +The x and y dimensions of the box used for median processing. +If \fIxmedian\fR > 1 or \fIymedian\fR is > 1, +then the median is calculated for each box and used in the surface +fit instead of the individual pixels. +.le +.ls median_percent = 50. +If the number of pixels in the median box is less than \fImedian_percent\fR * +\fIxmedian\fR * \fIymedian\fR the box will be omitted from the fit. +.le +.ls upper = 0., lower = 0. +The number of sigma limits for pixel rejection. If \fIupper\fR > 0. or +\fIlower\fR > 0. and median processing is turned off, +pixel rejection is enabled. +.le +.ls ngrow = 0 +The radius in pixels for region growing. +Pixels within a distance of \fIngrow\fR pixels of +a rejected pixel are also rejected. +.le +.ls niter = 0 +The maximum number of iterations in the rejection cycle. +Rejection will be terminated if the number of rejected pixels is zero +or the number of iterations equals \fIniter\fR. +.le +.ls regions = "all" +The available options (with minimum match abbreviation) are: +.ls all +All points in the image are fit. +.le +.ls rows +The fit is performed on the image rows specified by \fIrows\fR. +.le +.ls columns +The fit is performed on the image columns specified by \fIcolumns\fR. +.le +.ls border +The fit is performed on a border around the image whose width is specified +by \fIborder\fR. +.le +.ls sections +The fit is performed on image sections listed in the file specified +by \fIsections\fR. +.le +.ls circle +The fit is performed on a circular region whose parameters are specified by +\fIcircle\fR. +.le +.ls invcircle +The fit is performed on a region exterior to the circular region whose +parameters are specified by \fIcircle\fR. +.le +.le +.ls rows = "*" +When \fIregion_type\fR = 'rows', the string parameter \fIrows\fR specifies +the rows to be fit. +.le +.ls columns = "*" +When \fIregion_type\fR = 'columns', the string parameter \fIcolumns\fR +specifies the columns to be fit. +.le +.ls border = "50" +When \fIregion_type\fR = 'border', the +string parameter \fIborder\fR specifies the width of the border to be fit. +.le +.ls sections = "" +When \fIregion_type\fR = 'sections', the +string parameter \fIsections\fR is the name of the file containing the list of +image sections to be fit, where \fISections\fR may be the standard +input (STDIN). +The sections must be listed one per line in the following form: x1 x2 y1 y2. +.le +.ls circle = "" +The string parameter \fIcircle\fR lists the parameter needed to specify +the circle in the following format: xcenter ycenter radius. The three +parameters must be integers. +.le +.ls div_min = INDEF +When \fItype_output\fR = 'response' all divisions in which the fitted value +is below \fIdiv_min\fR are set to the value 1. +.le +.ih +DESCRIPTION +A surface is fit to selected portions of the input image. +The user may elect to fit the whole image, \fIregion_type\fR = 'all', +selected rows, \fIregion_type\fR = 'rows', selected columns, +\fIregion_type\fR = 'columns', a +border around the image, \fIregion_type\fR = 'border' or image sections, +\fIregion_type\fR = 'sections'. If the sections option is enabled the user +must supply the name of the file containing a list of sections, +\fIsections\fR = 'list', or enter them from the standard input. In either case +the sections must be listed one per line in the following form: x1 x2 y1 y2. + +The parameter \fIsurface_type\fR may be a +"legendre" polynomial, "chebyshev" polynomial, +a cubic spline ("spline3") or a linear spline ("spline1"). +The order of the polynomials is selected in both x and y. +Cross terms for the polynomial surfaces are optional. +For the cubic spline the parameters \fIxorder\fR and \fIyorder\fR specify +the number of polynomial pieces to be fit to the surface in +each direction. + +The output image may be the fitted image, the difference between the +input and the fitted image, the ratio of the input to the fitted image +or the input image with deviant pixels in the fitted regions replaced +with the fitted values, according to whether \fItype_output\fR = +'fit', 'residual', +'response' or 'clean'. If \fItype_output\fR = 'response' then pixels in the +fitted image with values < \fIdiv_min\fR are replaced by 1. +If \fItype_output\fR = +'clean' then at least one of \fIupper\fR or \fIlower\fR must be > 0. + +Pixel rejection is enabled if median processing is turned off, +\fIniter\fR > 0, +and at least one of the parameters \fIupper\fR and \fIlower\fR is > 0. +Region growing +can be turned on by setting \fIngrow\fR > 0, in which case all pixels within +a radius ngrow of a deviant pixel will be rejected. + +.ih +EXAMPLES +1. To create a smoothed version of an image: + +.nf + cl> imsurfit m74 m74smooth 5 10 function=spline3 +.fi + +2. To create a smoothed version of an image using median processing: + +.nf + cl> imsurfit m74 m74med 5 10 function=spline3 \ + >>> xmed=5 ymed=5 +.fi + +3. To subtract a constant background from an image: + +.nf + cl> imsurfit abell30 abell30bck 1 1 function=leg \ + >>> type=resid +.fi + +4. To make a ratio image using signals above 1000 units: + +.nf + cl> imsurfit n7006 n7006ratio 20 20 function=spline3 \ + >>> type=response div_min=1000 +.fi + +.ih +TIMINGS +Fitting and subtracting a constant from a 512 by 512 IRAF image requires +~35 cpu seconds. Approximately 130 cpu seconds are required to fit a +second degree polynomial in x and y (including cross-terms) to a +100 pixel wide border around a 512 by +512 IRAF image, and to subtract the fitted image from the input image. +To produce a smooth 512 by 512 IRAF image using a 10 by 10 bicubic spline +requires ~300 cpu seconds. Timings refer to a VAX 11/750 + fpa. + +.ih +NOTES +The surface fitting code uses the IRAF SURFIT math routines, +which have been optimized for image fitting . +The routines which fit selected portions +of the image, perform pixel rejection and region growing, and create and +maintain a list of rejected pixels utilize the ranges and pixlist packages +of routines currently maintained in the images directory. These will be +replaced by more general ranges and image masking routines in the future. +.endhelp diff --git a/pkg/images/imfit/doc/lineclean.hlp b/pkg/images/imfit/doc/lineclean.hlp new file mode 100644 index 00000000..9ce2b95f --- /dev/null +++ b/pkg/images/imfit/doc/lineclean.hlp @@ -0,0 +1,129 @@ +.help lineclean May85 images.imfit +.ih +NAME +lineclean -- replace deviant pixels in image lines +.ih +USAGE +.nf +lineclean input output +.fi +.ih +PARAMETERS +.ls input +Input images to be cleaned. +.le +.ls output +Output cleaned images. The number of output images must be the same as the +number of input images. +.le +.ls sample = "*" +Columns to be used in fitting the cleaning function. +.le +.ls naverage = 1 +Number of sample points to combined to create a fitting point. +A positive value specifies an average and a negative value specifies +a median. +.le +.ls function = spline3 +Cleaning function to be fit to the image lines. The functions are: +.ls legendre +Legendre polynomial of the specified order. +.le +.ls chebyshev +Chebyshev polynomial of the specified order. +.le +.ls spline1 +Linear spline of the specified number of pieces. +.le +.ls spline3 +Cubic spline of the specified number of pieces. +.le +.le +.ls order = 1 +The order of the polynomials or the number of spline pieces. +.le +.ls low_reject = 2.5, high_reject = 2.5 +Rejection limits below and above the fit in units of the residual sigma. +.le +.ls niterate = 1 +Number of rejection iterations. +.le +.ls grow = 1. +When a pixel is rejected, pixels within this distance of the rejected pixel +are also rejected. +.le +.ls graphics = "stdgraph" +Graphics output device for interactive graphics. +.le +.ls cursor = "stdgcur" +Graphics cursor input. +.le +.ih +DESCRIPTION +A one dimensional function is fit to each line of the input images. +The function may be a legendre polynomial, chebyshev polynomial, +linear spline, or cubic spline of a given order or number of spline pieces. +If \fIlow_reject\fR and/or \fIhigh_reject\fR are greater than zero the sigma +of the residuals between the fitted points and the fitted function is computed +and those points whose residuals are less than \fI-low_reject\fR * sigma +and greater than \fIhigh_reject\fR * sigma are excluded from the fit. +Points within a distance of \fIgrow\fR pixels of a rejected pixel are also +excluded from the fit. The function is then refit without the rejected points. +This rejection procedure may be iterated a number of times given by the +parameter \fIniterate\fR. Finally, the +rejected points in the input image are replaced by the fitted values +to create the output image lines. + +The output image may exist in which case a section in the input image is +applied to the output image. Thus, a section on the input image causes only +that part of the output image to be cleaned. If the output image does not +exist it is first created by making a copy of the full (without a section) +input image. + +The points fit are determined by selecting a sample of columns specified by +the parameter \fIsample\fR and taking either the average or median of +the number of points specified by the parameter \fInaverage\fR. +The type of averaging is selected by the sign of the parameter and the number +of points is selected by the absolute value of the parameter. +The sample points are specified relative to any image section. + +The fitting parameters (\fIsample, naverage, function, order, low_reject, +high_reject, niterate, grow\fR) +may be adjusted interactively if the parameter \fIinteractive\fR is yes. +Lines from the image are selected to be fit with the \fBicfit\fR package. +For images of greater than two dimensions sets of numbers giving the +2nd, 3rd, etc. coordinates are entered. +The image lines are specified relative to any image section. +When an end-of-file or no line is given then the last selected fitting +parameters are used on each line of the image. This step is repeated for +each image in the input list. The interactive options are described +in the help information \fBicfit\fR. +.ih +EXAMPLES +1. To clean pixels deviating by more than 2.5 sigma: + + cl> lineclean image cleanimage + +If the interactive flag is set then a prompt for an image line is +printed: + + image: Fit line = 100 + +For a one or two dimensional image the line number is entered (1 for a one +dimensional image). For a three dimensional image two numbers are entered. +For example: + + image: Fit line = 10 2 + +for line 10 of the second image plane. + +The selected line is graphed and the interactive options for setting and +fitting the line are used. Data points marked with diamonds indicate +points to be replaced by the fitted value. Exiting with 'q' or return +prompts for another line. When the fitting parameters are suitably set +then respond with end-of-file or return to fit all the lines of the image +and create the output image. +.ih +SEE ALSO +fit1d, xtools.icfit, imsurfit +.endhelp diff --git a/pkg/images/imfit/fit1d.par b/pkg/images/imfit/fit1d.par new file mode 100644 index 00000000..f28100ba --- /dev/null +++ b/pkg/images/imfit/fit1d.par @@ -0,0 +1,16 @@ +input,s,a,,,,Images to be fit +output,s,a,,,,Output images +bpm,s,h,"",,,Bad pixel mask(s) +axis,i,h,1,1,2,Axis to be fit +type,s,a,,,,"Type of output (fit, difference, ratio)" +interactive,b,h,yes,,,Set fitting parameters interactively? +sample,s,h,"*",,,Sample points to use in fit +naverage,i,h,1,,,Number of points in sample averaging +function,s,h,"spline3","spline3|legendre|chebyshev|spline1",,Fitting function +order,i,h,1,1,,Order of fitting function +low_reject,r,h,0.,0.,,Low rejection in sigma of fit +high_reject,r,h,0.,0.,,High rejection in sigma of fit +niterate,i,h,1,0,,Number of rejection iterations +grow,r,h,0.,0.,,Rejection growing radius in pixels +graphics,s,h,"stdgraph",,,Graphics output device +cursor,*gcur,h,"",,,Graphics cursor input diff --git a/pkg/images/imfit/imfit.cl b/pkg/images/imfit/imfit.cl new file mode 100644 index 00000000..acde0687 --- /dev/null +++ b/pkg/images/imfit/imfit.cl @@ -0,0 +1,13 @@ +#{ IMFIT -- The Image Fitting Package. + +set imfit = "images$imfit/" + +package imfit + +# Tasks. + +task fit1d, + imsurfit, + lineclean = "imfit$x_images.e" + +clbye() diff --git a/pkg/images/imfit/imfit.hd b/pkg/images/imfit/imfit.hd new file mode 100644 index 00000000..adcc4d44 --- /dev/null +++ b/pkg/images/imfit/imfit.hd @@ -0,0 +1,10 @@ +# Help directory for the IMFIT package + +$doc = "images$imfit/doc/" +$src = "images$imfit/src/" + +fit1d hlp=doc$fit1d.hlp, src=src$fit1d.x +imsurfit hlp=doc$imsurfit.hlp, src=src$t_imsurfit.x +lineclean hlp=doc$lineclean.hlp, src=src$t_lineclean.x +revisions sys=Revisions + diff --git a/pkg/images/imfit/imfit.men b/pkg/images/imfit/imfit.men new file mode 100644 index 00000000..793b1c5e --- /dev/null +++ b/pkg/images/imfit/imfit.men @@ -0,0 +1,3 @@ + fit1d - Fit a function to image lines or columns + imsurfit - Fit a surface to a 2-D image + lineclean - Replace deviant pixels in image lines diff --git a/pkg/images/imfit/imfit.par b/pkg/images/imfit/imfit.par new file mode 100644 index 00000000..cef3f3ff --- /dev/null +++ b/pkg/images/imfit/imfit.par @@ -0,0 +1 @@ +version,s,h,"Jan97" diff --git a/pkg/images/imfit/imsurfit.par b/pkg/images/imfit/imsurfit.par new file mode 100644 index 00000000..1f21ffe5 --- /dev/null +++ b/pkg/images/imfit/imsurfit.par @@ -0,0 +1,24 @@ +# IMSURFIT + +input,f,a,,,,Input images to be fit +output,f,a,,,,Output images +xorder,i,a,2,1,,Order of function in x +yorder,i,a,2,1,,Order of function in y +type_output,s,h,'fit',,,'Type of output (fit,residual,response,clean)' +function,s,h,'leg',,,'Function to be fit (legendre,chebyshev,spline3)' +cross_terms,b,h,y,,,Include cross-terms for polynomials? +xmedian,i,h,1,1,,X length of median box +ymedian,i,h,1,1,,Y length of median box +median_percent,r,h,50.,,,Minimum fraction of pixels in median box +lower,r,h,0.0,0.0,,Lower limit for residuals +upper,r,h,0.0,0.0,,Upper limit for residuals +ngrow,i,h,0,0,,Radius of region growing circle +niter,i,h,0,0,,Maximum number of rejection cycles +regions,s,h,'all',,, 'Good regions (all,rows,columns,border,sections,circle,invcircle)' +rows,s,h,'*',,,Rows to be fit +columns,s,h,'*',,,Columns to be fit +border,s,h,'50',,,Width of border to be fit +sections,s,h,,,,File name for sections list +circle,s,h,,,,Circle specifications +div_min,r,h,INDEF,,,Division minimum for response output +mode,s,h,'ql' diff --git a/pkg/images/imfit/lineclean.par b/pkg/images/imfit/lineclean.par new file mode 100644 index 00000000..5942f03f --- /dev/null +++ b/pkg/images/imfit/lineclean.par @@ -0,0 +1,13 @@ +input,s,a,,,,Images to be cleaned +output,s,a,,,,Output images +interactive,b,h,yes,,,Set fitting parameters interactively? +sample,s,h,"*",,,Sample points to use in fit +naverage,i,h,1,,,Number of points in sample averaging +function,s,h,"spline3","spline3|legendre|chebyshev|spline1",,Fitting function +order,i,h,1,1,,Order of fitting function +low_reject,r,h,2.5,0.,,Low rejection in sigma of fit +high_reject,r,h,2.5,0.,,High rejection in sigma of fit +niterate,i,h,1,0,,Number of rejection iterations +grow,r,h,1.,0.,,Rejection growing radius in pixels +graphics,s,h,"stdgraph",,,Graphics output device +cursor,*gcur,h,"",,,Graphics cursor input diff --git a/pkg/images/imfit/mkpkg b/pkg/images/imfit/mkpkg new file mode 100644 index 00000000..a74a627e --- /dev/null +++ b/pkg/images/imfit/mkpkg @@ -0,0 +1,5 @@ +# MKPKG for the IMFIT Package + +libpkg.a: + @src + ; diff --git a/pkg/images/imfit/src/fit1d.x b/pkg/images/imfit/src/fit1d.x new file mode 100644 index 00000000..84ffddf1 --- /dev/null +++ b/pkg/images/imfit/src/fit1d.x @@ -0,0 +1,597 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <pkg/gtools.h> +include <error.h> + +define MAXBUF (512*100) # Maximum number of pixels per block + + +# FIT1D -- Fit a function to image lines or columns and output an image +# consisting of the fit, the difference, or the ratio. The fitting parameters +# may be set interactively using the icfit package. + +procedure t_fit1d () + +int listin # Input image list +int listout # Output image list +int listbpm # Bad pixel mask list +bool interactive # Interactive? + +char sample[SZ_LINE] # Sample ranges +int naverage # Sample averaging size +char function[SZ_LINE] # Curve fitting function +int order # Order of curve fitting function +real low_reject, high_reject # Rejection thresholds +int niterate # Number of rejection iterations +real grow # Rejection growing radius + +int axis # Image axis to fit +int ntype # Type of output +char input[SZ_LINE] # Input image +char output[SZ_FNAME] # Output image +char bpm[SZ_FNAME] # Bad pixel mask +pointer in, out, bp # IMIO pointers +pointer ic # ICFIT pointer +pointer gt # GTOOLS pointer + +bool same, clgetb() +int imtopen(), imtgetim(), imtlen(), strdic(), gt_init() +int clgeti() +real clgetr() + +begin + # Get input and output lists and check that the number of images + # are the same. + + call clgstr ("input", input, SZ_LINE) + listin = imtopen (input) + call clgstr ("output", input, SZ_LINE) + listout = imtopen (input) + if (imtlen (listin) != imtlen (listout)) { + call imtclose (listin) + call imtclose (listout) + call error (0, "Input and output image lists do not match") + } + call clgstr ("bpm", input, SZ_LINE) + listbpm = imtopen (input) + if (imtlen (listbpm) > 1 && imtlen (listin) != imtlen (listbpm)) { + call imtclose (listin) + call imtclose (listout) + call imtclose (listbpm) + call error (0, "Input and mask lists do not match") + } + + # Get task parameters. + + axis = clgeti ("axis") + call clgstr ("type", input, SZ_LINE) + call clgstr ("sample", sample, SZ_LINE) + naverage = clgeti ("naverage") + call clgstr ("function", function, SZ_LINE) + order = clgeti ("order") + low_reject = clgetr ("low_reject") + high_reject = clgetr ("high_reject") + niterate = clgeti ("niterate") + grow = clgetr ("grow") + interactive = clgetb ("interactive") + + # Decode the output type and initialize the curve fitting package. + + ntype = strdic (input, input, SZ_LINE, "|fit|difference|ratio|") + if (ntype == 0) + call error (0, "Unknown output type") + + # Set the ICFIT pointer structure. + call ic_open (ic) + call ic_pstr (ic, "sample", sample) + call ic_puti (ic, "naverage", naverage) + call ic_pstr (ic, "function", function) + call ic_puti (ic, "order", order) + call ic_putr (ic, "low", low_reject) + call ic_putr (ic, "high", high_reject) + call ic_puti (ic, "niterate", niterate) + call ic_putr (ic, "grow", grow) + call ic_pstr (ic, "ylabel", "") + + gt = gt_init() + call gt_sets (gt, GTTYPE, "line") + + # Fit the lines in each input image. + + bpm[1] = EOS + while ((imtgetim (listin, input, SZ_LINE) != EOF) && + (imtgetim (listout, output, SZ_FNAME) != EOF)) { + if (imtgetim (listbpm, bpm, SZ_FNAME) == EOF) + ; + + iferr (call f1d_immap (input,output,bpm,ntype,in,out,bp,same)) { + call erract (EA_WARN) + next + } + call f1d_fit1d (in,out,bp,ic,gt,input,axis,ntype,interactive) + call imunmap (in) + if (!same) + call imunmap (out) + if (bp != NULL) + call yt_pmunmap (bp) + } + + call ic_closer (ic) + call gt_free (gt) + call imtclose (listin) + call imtclose (listout) +end + + +# F1D_FIT1D -- Given the image descriptor determine the fitting function +# for each line or column and create an output image. If the interactive flag +# is set then set the fitting parameters interactively. + +procedure f1d_fit1d (in, out, bp, ic, gt, title, axis, ntype, interactive) + +pointer in # IMIO pointer for input image +pointer out # IMIO pointer for output image +pointer bp # IMIO pointer for bad pixel mask +pointer ic # ICFIT pointer +pointer gt # GTOOLS pointer +char title[ARB] # Title +int axis # Image axis to fit +int ntype # Type of output +bool interactive # Interactive? + +char graphics[SZ_FNAME] # Graphics device +int i, nx, new +real div +pointer cv, gp, sp, x, wts, indata, outdata + +int f1d_getline(), f1d_getdata(), strlen() +real cveval() +pointer gopen() + +begin + # Error check. + + if (IM_NDIM (in) > 2) + call error (0, "Image dimensions > 2 are not implemented") + if (axis > IM_NDIM (in)) + call error (0, "Axis exceeds image dimension") + + # Allocate memory for curve fitting. + + nx = IM_LEN (in, axis) + call smark (sp) + call salloc (x, nx, TY_REAL) + + do i = 1, nx + Memr[x+i-1] = i + + call ic_putr (ic, "xmin", Memr[x]) + call ic_putr (ic, "xmax", Memr[x+nx-1]) + + # If the interactive flag is set then use icg_fit to set the + # fitting parameters. Get_fitline returns EOF when the user + # is done. The weights are reset since the user may delete + # points. + + if (interactive) { + call clgstr ("graphics", graphics, SZ_FNAME) + gp = gopen (graphics, NEW_FILE, STDGRAPH) + + i = strlen (title) + indata = NULL + while (f1d_getline (ic,gt,in,bp,axis,title,indata,wts) != EOF) { + title[i + 1] = EOS + call icg_fit (ic, gp, "cursor", gt, cv, Memr[x], Memr[indata], + Memr[wts], nx) + } + call mfree (indata, TY_REAL) + call mfree (wts, TY_REAL) + call gclose (gp) + } + + # Loop through the input image and create an output image. + + new = YES + + while (f1d_getdata (in,out,bp,axis,MAXBUF,indata,outdata,wts) != EOF) { + + call ic_fit (ic, cv, Memr[x], Memr[indata], Memr[wts], + nx, new, YES, new, new) + new = NO + + # Be careful because the indata and outdata buffers may be the same. + switch (ntype) { + case 1: + call cvvector (cv, Memr[x], Memr[outdata], nx) + case 2: + do i = 0, nx-1 + Memr[outdata+i] = Memr[indata+i] - cveval (cv, Memr[x+i]) + case 3: + do i = 0, nx-1 { + div = cveval (cv, Memr[x+i]) + if (abs (div) < 1E-20) + div = 1 + Memr[outdata+i] = Memr[indata+i] / div + } + } + } + + call cvfree (cv) + call mfree (wts, TY_REAL) + call sfree (sp) +end + + +# F1D_IMMAP -- Map images for fit1d. + +procedure f1d_immap (input, output, bpm, ntype, in, out, bp, same) + +char input[ARB] # Input image +char output[ARB] # Output image +char bpm[ARB] # Bad pixel mask +int ntype # Type of fit1d output +pointer in # Input IMIO pointer +pointer out # Output IMIO pointer +pointer bp # Mask IMIO pointer +bool same # Same image? + +int i +pointer sp, iroot, isect, oroot, osect, line, data + +bool streq() +int imaccess(), impnlr() +pointer immap(), yt_pmmap() +errchk immap, yt_pmmap + +begin + # Get the root name and section of the input image. + + call smark (sp) + call salloc (iroot, SZ_FNAME, TY_CHAR) + call salloc (isect, SZ_FNAME, TY_CHAR) + call salloc (oroot, SZ_FNAME, TY_CHAR) + call salloc (osect, SZ_FNAME, TY_CHAR) + + call imgimage (input, Memc[iroot], SZ_FNAME) + call imgsection (input, Memc[isect], SZ_FNAME) + call imgimage (output, Memc[oroot], SZ_FNAME) + call imgsection (output, Memc[osect], SZ_FNAME) + same = streq (Memc[iroot], Memc[oroot]) + + # If the output image is not accessible then create it as a new copy + # of the full input image and initialize according to ntype. + + if (imaccess (output, READ_WRITE) == NO) { + in = immap (Memc[iroot], READ_ONLY, 0) + out = immap (Memc[oroot], NEW_COPY, in) + IM_PIXTYPE(out) = TY_REAL + + call salloc (line, IM_MAXDIM, TY_LONG) + call amovkl (long (1), Meml[line], IM_MAXDIM) + + switch (ntype) { + case 1, 2: + while (impnlr (out, data, Meml[line]) != EOF) + call aclrr (Memr[data], IM_LEN(out, 1)) + case 3: + while (impnlr (out, data, Meml[line]) != EOF) + call amovkr (1., Memr[data], IM_LEN(out, 1)) + } + + call imunmap (in) + call imunmap (out) + } + + # Map the images. If the output image has a section + # then use it. If the input image has a section and the output image + # does not then add the image section to the output image. Finally + # check the input and output images have the same size. + + in = immap (input, READ_ONLY, 0) + + if (Memc[isect] != EOS && Memc[osect] == EOS) { + call sprintf (Memc[osect], SZ_FNAME, "%s%s") + call pargstr (Memc[oroot]) + call pargstr (Memc[isect]) + } else + call strcpy (output, Memc[osect], SZ_FNAME) + + if (streq (input, Memc[osect])) { + call imunmap (in) + in = immap (input, READ_WRITE, 0) + out = in + } else + out = immap (Memc[osect], READ_WRITE, 0) + + do i = 1, IM_NDIM(in) + if (IM_LEN(in, i) != IM_LEN(out, i)) { + call imunmap (in) + if (!same) + call imunmap (out) + call sfree (sp) + call error (0, "Input and output images have different sizes") + } + + bp = yt_pmmap (bpm, in, Memc[iroot], SZ_FNAME) + + call sfree (sp) +end + + +# F1D_GETDATA -- Get a line of image data. + +int procedure f1d_getdata (in, out, bp, axis, maxbuf, indata, outdata, wts) + +pointer in # Input IMIO pointer +pointer out # Output IMIO pointer +pointer bp # Bad pixel mask IMIO pointer +int axis # Image axis +int maxbuf # Maximum buffer size for column axis +pointer indata # Input data pointer +pointer outdata # Output data pointer +pointer wts # Weights pointer + +int i, index, last_index, col1, col2, nc, ncols, nlines, ncols_block +pointer inbuf, outbuf, wtbuf, ptr +pointer imgl1r(), imgl1s(), impl1r(), imgl2r(), imgl2s(), impl2r() +pointer imgs2r(), imgs2s(), imps2r() +data index/0/ + +begin + # Increment to the next image vector. + + index = index + 1 + + # Initialize for the first vector. + + if (index == 1) { + ncols = IM_LEN (in, 1) + if (IM_NDIM (in) == 1) + nlines = 1 + else + nlines = IM_LEN (in, 2) + + switch (axis) { + case 1: + last_index = nlines + + call malloc (wts, ncols, TY_REAL) + case 2: + last_index = ncols + ncols_block = max (1, min (ncols, maxbuf / nlines)) + col2 = 0 + + call malloc (indata, nlines, TY_REAL) + call malloc (outdata, nlines, TY_REAL) + call malloc (wts, nlines, TY_REAL) + } + } + + # Finish up if the last vector has been done. + + if (index > last_index) { + switch (axis) { + case 1: + call mfree (wts, TY_REAL) + case 2: + ptr = outbuf + index - 1 - col1 + do i = 1, nlines { + Memr[ptr] = Memr[outdata+i-1] + ptr = ptr + nc + } + + call mfree (indata, TY_REAL) + call mfree (outdata, TY_REAL) + call mfree (wts, TY_REAL) + } + + index = 0 + return (EOF) + } + + # Get the next image vector. + + switch (axis) { + case 1: + ncols = IM_LEN(in,1) + if (IM_NDIM (in) == 1) { + indata = imgl1r (in) + outdata = impl1r (out) + if (bp == NULL) + call amovkr (1., Memr[wts], ncols) + else { + wtbuf = imgl1s (bp) + do i = 0, ncols-1 { + if (Mems[wtbuf+i] == 0) + Memr[wts+i] = 1. + else + Memr[wts+i] = 0. + } + } + } else { + indata = imgl2r (in, index) + outdata = impl2r (out, index) + if (bp == NULL) + call amovkr (1., Memr[wts], ncols) + else { + wtbuf = imgl2s (bp, index) + do i = 0, ncols-1 { + if (Mems[wtbuf+i] == 0) + Memr[wts+i] = 1. + else + Memr[wts+i] = 0. + } + } + } + case 2: + if (index > 1) { + ptr = outbuf + index - 1 - col1 + do i = 1, nlines { + Memr[ptr] = Memr[outdata+i-1] + ptr = ptr + nc + } + } + + if (index > col2) { + col1 = col2 + 1 + col2 = min (ncols, col1 + ncols_block - 1) + inbuf = imgs2r (in, col1, col2, 1, nlines) + outbuf = imps2r (out, col1, col2, 1, nlines) + if (bp != NULL) + wtbuf = imgs2s (bp, col1, col2, 1, nlines) + nc = col2 - col1 + 1 + } + + ptr = inbuf + index - col1 + do i = 0, nlines-1 { + Memr[indata+i] = Memr[ptr] + ptr = ptr + nc + } + + if (bp == NULL) + call amovkr (1., Memr[wts], nlines) + else { + ptr = wtbuf + index - col1 + do i = 0, nlines-1 { + if (Mems[ptr] == 0) + Memr[wts+i] = 1. + else + Memr[wts+i] = 0. + ptr = ptr + nc + } + } + } + + return (index) +end + + +# F1D_GETLINE -- Get image data to be fit interactively. Return EOF +# when the user enters EOF or CR. Default is 1 and the out of bounds +# requests are silently limited to the nearest in edge. + +int procedure f1d_getline (ic, gt, im, bp, axis, title, data, wts) + +pointer ic # ICFIT pointer +pointer gt # GTOOLS pointer +pointer im # IMIO pointer input image +pointer bp # IMIO pointer for bad pixel mask +int axis # Image axis +char title[ARB] # Title +pointer data # Image data +pointer wts # Weights + +pointer x, wtbuf +char line[SZ_LINE] +int i, j, stat, imlen +int getline(), nscan() +pointer imgl1r(), imgl1s() +data stat/EOF/ + +begin + # If the image is one dimensional do not prompt. + + if (IM_NDIM (im) == 1) { + if (stat == EOF) { + call sprintf (title, SZ_LINE, "%s\n%s") + call pargstr (title) + call pargstr (IM_TITLE(im)) + call gt_sets (gt, GTTITLE, title) + call mfree (data, TY_REAL) + imlen = IM_LEN(im,1) + call malloc (data, imlen, TY_REAL) + call amovr (Memr[imgl1r(im)], Memr[data], imlen) + call malloc (wts, imlen, TY_REAL) + if (bp == NULL) + call amovkr (1., Memr[wts], imlen) + else { + wtbuf = imgl1s (bp) + do i = 0, imlen-1 { + if (Mems[wtbuf+i] == 0) + Memr[wts+i] = 1. + else + Memr[wts+i] = 0. + } + } + stat = OK + } else + stat = EOF + + return (stat) + } + + # If the image is two dimensional prompt for the line or column. + + switch (axis) { + case 1: + imlen = IM_LEN (im, 2) + call sprintf (title, SZ_LINE, "%s: Fit line =") + call pargstr (title) + case 2: + imlen = IM_LEN (im, 1) + call sprintf (title, SZ_LINE, "%s: Fit column =") + call pargstr (title) + } + + call printf ("%s ") + call pargstr (title) + call flush (STDOUT) + + if (getline(STDIN, line) == EOF) + return (EOF) + + call sscan (line) + call gargi (i) + call gargi (j) + + switch (nscan()) { + case 0: + stat = EOF + return (stat) + case 1: + i = max (1, min (imlen, i)) + j = i + case 2: + i = max (1, min (imlen, i)) + j = max (1, min (imlen, j)) + } + + call sprintf (title, SZ_LINE, "%s %d - %d\n%s") + call pargstr (title) + call pargi (i) + call pargi (j) + call pargstr (IM_TITLE(im)) + + call gt_sets (gt, GTTITLE, title) + + call malloc (wts, imlen, TY_REAL) + switch (axis) { + case 1: + call ic_pstr (ic, "xlabel", "Column") + call xt_21imavg (im, axis, 1, IM_LEN(im,1), i, j, x, data, imlen) + if (bp != NULL) + call xt_21imsum (bp, axis, 1, IM_LEN(im,1), i, j, x, wts, imlen) + case 2: + call ic_pstr (ic, "xlabel", "Line") + call xt_21imavg (im, axis, i, j, 1, IM_LEN(im,2), x, data, imlen) + if (bp != NULL) + call xt_21imsum (bp, axis, i, j, 1, IM_LEN(im,2), x, wts, imlen) + } + if (bp == NULL) { + call mfree (wts, TY_REAL) + call malloc (wts, imlen, TY_REAL) + call amovkr (1., Memr[wts], imlen) + } else { + do i = 0, imlen-1 { + if (Memr[wts+i] == 0.) + Memr[wts+i] = 1. + else + Memr[wts+i] = 0. + } + } + call mfree (x, TY_REAL) + + stat = OK + return (stat) +end diff --git a/pkg/images/imfit/src/imsurfit.h b/pkg/images/imfit/src/imsurfit.h new file mode 100644 index 00000000..84c077ec --- /dev/null +++ b/pkg/images/imfit/src/imsurfit.h @@ -0,0 +1,40 @@ +# Header file for IMSURFIT + +define LEN_IMSFSTRUCT 20 + +# surface parameters +define SURFACE_TYPE Memi[$1] +define XORDER Memi[$1+1] +define YORDER Memi[$1+2] +define CROSS_TERMS Memi[$1+3] +define TYPE_OUTPUT Memi[$1+4] + +# median processing parameters +define MEDIAN Memi[$1+5] +define XMEDIAN Memi[$1+6] +define YMEDIAN Memi[$1+7] +define MEDIAN_PERCENT Memr[P2R($1+8)] + +# pixel rejection parameters +define REJECT Memi[$1+9] +define NGROW Memi[$1+10] +define NITER Memi[$1+11] +define LOWER Memr[P2R($1+12)] +define UPPER Memr[P2R($1+13)] + +define DIV_MIN Memr[P2R($1+14)] + +# definitions for type_output +define FIT 1 +define CLEAN 2 +define RESID 3 +define RESP 4 + +# definitions for good regions +define ALL 1 +define COLUMNS 2 +define ROWS 3 +define BORDER 4 +define SECTIONS 5 +define CIRCLE 6 +define INVCIRCLE 7 diff --git a/pkg/images/imfit/src/imsurfit.x b/pkg/images/imfit/src/imsurfit.x new file mode 100644 index 00000000..9f655f52 --- /dev/null +++ b/pkg/images/imfit/src/imsurfit.x @@ -0,0 +1,1172 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <imhdr.h> +include <math/surfit.h> +include "imsurfit.h" + +# IMSURFIT -- Procedure to fit a surface to a single image including +# optional pixel rejection. + +procedure imsurfit (imin, imout, imfit, gl) + +pointer imin # pointer to the input image +pointer imout # pointer to the output image +pointer imfit # pointer to the imsurfit parameters +pointer gl # pointer to the good regions list + +pointer sf, rl +errchk isfree, prl_free +errchk all_pixels, good_pixels, good_median, all_medians, do_reject +errchk set_outimage + +begin + sf = NULL + rl = NULL + + # Accumulate and solve the surface. + if (gl == NULL) { + if (MEDIAN(imfit) == NO) + call all_pixels (imin, imfit, sf) + else + call all_medians (imin, imfit, sf) + } else { + if (MEDIAN(imfit) == NO) + call good_pixels (imin, imfit, gl, sf) + else + call good_medians (imin, imfit, gl, sf) + } + + # Perform the reject cycle. + if (REJECT(imfit) == YES || TYPE_OUTPUT(imfit) == CLEAN) + call do_reject (imin, imfit, gl, sf, rl) + + # Evaluate surface for appropriate output type. + call set_outimage (imin, imout, imfit, sf, rl) + + # Cleanup. + call prl_free (rl) + call isfree (sf) + + rl = NULL + sf = NULL +end + + +# ALL_PIXELS -- Accumulate surface when there are no bad regions +# and no median processing. + +procedure all_pixels (im, imfit, sf) + +pointer im # pointer to the input image +pointer imfit # pointer to the imsurfit structure +pointer sf # pointer to the surface descriptor + +int i, lp, ncols, nlines, ier +long v[IM_MAXDIM] +pointer sp, cols, lines, wgt, lbuf +int imgnlr() +errchk smark, salloc, sfree, imgnlr +errchk isinit, islfit, islrefit, issolve + +begin + ncols = IM_LEN(im, 1) + nlines = IM_LEN(im,2) + + # Initialize the surface fit. + call isinit (sf, SURFACE_TYPE(imfit), XORDER(imfit), YORDER(imfit), + CROSS_TERMS(imfit), ncols, nlines) + + # Allocate working space for fitting. + call smark (sp) + call salloc (cols, ncols, TY_INT) + call salloc (lines, nlines, TY_INT) + call salloc (wgt, ncols, TY_REAL) + + # Initialize the x and weight buffers. + do i = 1, ncols + Memi[cols - 1 + i] = i + call amovkr (1.0, Memr[wgt], ncols) + + # Loop over image lines. + lp = 0 + call amovkl (long (1), v, IM_MAXDIM) + do i = 1, nlines { + + # Read in the image line. + if (imgnlr (im, lbuf, v) == EOF) + call error (0, "Error reading image") + + # Fit each image line. + if (i == 1) + call islfit (sf, Memi[cols], i, Memr[lbuf], Memr[wgt], + ncols, SF_USER, ier) + else + call islrefit (sf, Memi[cols], i, Memr[lbuf], Memr[wgt]) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call eprintf ("Warning: Too few columns to fit line: %d\n") + call pargi (i) + case SINGULAR: + call eprintf ("Warning: Solution singular for line: %d\n") + call pargi (i) + Memi[lines + lp] = i + lp = lp + 1 + default: + Memi[lines + lp] = i + lp = lp + 1 + } + + } + + # Solve the surface. + call issolve (sf, Memi[lines], lp, ier) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call error (0, "ALL_PIXELS: Cannot fit surface.") + case SINGULAR: + call eprintf ("Warning: Solution singular for surface.\n") + default: + # everything OK + } + + # Free space. + call sfree (sp) +end + + +# GOOD_PIXELS -- Get surface when good regions are defined and median +# processing is off. + +procedure good_pixels (im, imfit, gl, sf) + +pointer im # input image +pointer imfit # pointer to imsurfit header structure +pointer gl # pointer to good region list +pointer sf # pointer to the surface descriptor + +int lp, lineno, prevlineno, ncols, nlines, npts, nranges, ier, ijunk +int max_nranges +pointer sp, colsfit, lines, buf, fbuf, wgt, ranges +int prl_nextlineno(), prl_eqlines(), prl_get_ranges(), is_expand_ranges() +int is_choose_rangesr() +pointer imgl2r() + +errchk smark, salloc, sfree, imgl2r +errchk isinit, islfit, islrefit, issolve +errchk prl_nextlineno, prl_eqlines, prl_get_ranges +errchk is_choose_rangesr + +begin + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + max_nranges = ncols + + # Initialize the surface fit. + call isinit (sf, SURFACE_TYPE(imfit), XORDER(imfit), YORDER(imfit), + CROSS_TERMS(imfit), ncols, nlines) + + # Allocate temporary space for fitting. + call smark (sp) + call salloc (colsfit, ncols, TY_INT) + call salloc (lines, nlines, TY_INT) + call salloc (fbuf, ncols, TY_REAL) + call salloc (wgt, ncols, TY_REAL) + call salloc (ranges, 3 * max_nranges + 1, TY_INT) + call amovkr (1., Memr[wgt], ncols) + + # Intialize counters and pointers. + lp = 0 + lineno = 0 + prevlineno = 0 + + # Loop over those lines to be fit. + while (prl_nextlineno (gl, lineno) != EOF) { + + # Read in the image line. + buf = imgl2r (im, lineno) + if (buf == EOF) + call error (0, "GOOD_PIXELS: Error reading image.") + + # Get the ranges for that image line. + nranges = prl_get_ranges (gl, lineno, Memi[ranges], max_nranges) + if (nranges == 0) + next + + # If ranges are not equal to previous line fit else refit. + if (lp == 0 || prl_eqlines (gl, lineno, prevlineno) == NO) { + npts = is_expand_ranges (Memi[ranges], Memi[colsfit], ncols) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[buf], Memr[fbuf], + npts, 1, ncols) + call islfit (sf, Memi[colsfit], lineno, Memr[fbuf], Memr[wgt], + npts, SF_USER, ier) + } else { + ijunk = is_choose_rangesr (Memi[colsfit], Memr[buf], Memr[fbuf], + npts, 1, ncols) + call islrefit (sf, Memi[colsfit], lineno, Memr[fbuf], Memr[wgt]) + } + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call eprintf ("Warning: Too few columns to fit line: %d\n") + call pargi (lineno) + case SINGULAR: + call eprintf ("Warning: Solution singular for line: %d\n") + call pargi (lineno) + Memi[lines+lp] = lineno + lp = lp + 1 + default: + Memi[lines+lp] = lineno + lp = lp + 1 + } + + prevlineno = lineno + } + + # Solve the surface. + call issolve (sf, Memi[lines], lp, ier) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call error (0, "GOOD_PIXELS: Cannot fit surface.") + case SINGULAR: + call eprintf ("Warning: Solution singular for surface.\n") + default: + # everything OK + } + + # Free space. + call sfree (sp) +end + + +# ALL_MEDIANS -- Get surface when median processor on and all +# pixels good. + +procedure all_medians (im, imfit, sf) + +pointer im # input image +pointer imfit # pointer to the imsurfit header structure +pointer sf # pointer to the surface descriptor + +int i, lp, cp, op, lineno, x1, x2, y1, y2, ier +int nimcols, nimlines, ncols, nlines, npts +pointer sp, cols, lines, wgt, z, med, sbuf, lbuf, buf + +pointer imgs2r() +real asokr() +errchk salloc, sfree, smark +errchk isinit, islfit, islrefit, issolve + +begin + # Determine the number of lines and columns for a median processed + # image. + nimcols = IM_LEN(im,1) + if (mod (int (IM_LEN(im,1)), XMEDIAN(imfit)) != 0) + ncols = IM_LEN(im,1) / XMEDIAN(imfit) + 1 + else + ncols = IM_LEN(im,1) / XMEDIAN(imfit) + nimlines = IM_LEN(im,2) + if (mod (int (IM_LEN(im,2)), YMEDIAN(imfit)) != 0) + nlines = IM_LEN(im,2) / YMEDIAN(imfit) + 1 + else + nlines = IM_LEN(im,2) / YMEDIAN(imfit) + + # Initialize the surface fitting. + call isinit (sf, SURFACE_TYPE(imfit), XORDER(imfit), YORDER(imfit), + CROSS_TERMS(imfit), ncols, nlines) + + # Allocate workin memory. + call smark (sp) + call salloc (cols, ncols, TY_INT) + call salloc (wgt, ncols, TY_REAL) + call salloc (lines, nlines, TY_INT) + call salloc (z, ncols, TY_REAL) + call salloc (med, XMEDIAN(imfit) * YMEDIAN(imfit), TY_REAL) + + # Intialize the x and weight arrays. + do i = 1, ncols + Memi[cols - 1 + i] = i + call amovkr (1.0, Memr[wgt], ncols) + + # Loop over image sections. + lp = 0 + lineno = 1 + for (y1 = 1; y1 <= nimlines; y1 = y1 + YMEDIAN(imfit)) { + + # Get image section. + y2 = min (y1 + YMEDIAN(imfit) - 1, nimlines) + sbuf = imgs2r (im, 1, nimcols, y1, y2) + if (sbuf == EOF) + call error (0, "Error reading image section.") + + # Loop over median boxes. + cp = 0 + for (x1 = 1; x1 <= nimcols; x1 = x1 + XMEDIAN(imfit)) { + + x2 = min (x1 + XMEDIAN(imfit) - 1, nimcols) + npts = x2 - x1 + 1 + lbuf = sbuf - 1 + x1 + + # Loop over lines in the median box. + op = 0 + buf = lbuf + for (i = 1; i <= y2 - y1 + 1; i = i + 1) { + call amovr (Memr[buf], Memr[med+op], npts) + op = op + npts + buf = buf + nimcols + } + + # Calculate the median. + Memr[z+cp] = asokr (Memr[med], op, (op + 1) / 2) + cp = cp + 1 + + } + + # Fit each image "line". + if (y1 == 1) + call islfit (sf, Memi[cols], lineno, Memr[z], Memr[wgt], + ncols, SF_USER, ier) + else + call islrefit (sf, Memi[cols], lineno, Memr[z], Memr[wgt]) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call eprintf ("Warning: Too few columns to fit line: %d\n") + call pargi (lineno) + case SINGULAR: + call eprintf ("Warning: Solution singular for line: %d\n") + call pargi (lineno) + Memi[lines + lp] = lineno + lp = lp + 1 + default: + Memi[lines + lp] = lineno + lp = lp + 1 + } + + lineno = lineno + 1 + } + + # Solve th surface. + call issolve (sf, Memi[lines], lp, ier) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call error (0, "ALL_MEDIANS: Cannot fit surface.") + case SINGULAR: + call eprintf ("Warning: Solution singular for surface.\n") + default: + # everything OK + } + + # Free space + call sfree (sp) +end + + +# GOOD_MEDIANS -- Procedure to fetch medians when the good regions +# list is defined. + +procedure good_medians (im, imfit, gl, sf) + +pointer im # input image +pointer imfit # pointer to surface descriptor structure +pointer gl # pointer to good regions list +pointer sf # pointer the surface descriptor + +int i, cp, lp, x1, x2, y1, y2, ier, ntemp +int nimcols, nimlines, ncols, nlines, nranges, nbox, nxpts +int lineno, current_line, lines_per_box, max_nranges +pointer sp, colsfit, cols, lines, wgt, npts, lbuf, med, mbuf, z, ranges + +int prl_get_ranges(), prl_nextlineno(), is_expand_ranges() +int is_choose_rangesr() +pointer imgl2r() +real asokr() +errchk smark, salloc, sfree, imgl2r +errchk isinit, islfit, issolve +errchk prl_get_ranges, prl_nextlineno, is_choose_rangesr() + +begin + # Determine the number of lines and columns for a median processed + # image. + nimcols = IM_LEN(im,1) + if (mod (int (IM_LEN(im,1)), XMEDIAN(imfit)) != 0) + ncols = IM_LEN(im,1) / XMEDIAN(imfit) + 1 + else + ncols = IM_LEN(im,1) / XMEDIAN(imfit) + nimlines = IM_LEN(im,2) + if (mod (int (IM_LEN(im,2)), YMEDIAN(imfit)) != 0) + nlines = IM_LEN(im,2) / YMEDIAN(imfit) + 1 + else + nlines = IM_LEN(im,2) / YMEDIAN(imfit) + nbox = XMEDIAN(imfit) * YMEDIAN(imfit) + max_nranges = nimcols + + # Initialize the surface fitting. + call isinit (sf, SURFACE_TYPE(imfit), XORDER(imfit), YORDER(imfit), + CROSS_TERMS(imfit), ncols, nlines) + + # Allocate working memory. + call smark (sp) + call salloc (colsfit, nimcols, TY_INT) + call salloc (cols, ncols, TY_INT) + call salloc (npts, ncols, TY_INT) + call salloc (lines, nlines, TY_INT) + call salloc (wgt, ncols, TY_REAL) + call salloc (med, nbox * ncols, TY_REAL) + call salloc (z, ncols, TY_REAL) + call salloc (ranges, 3 * max_nranges + 1, TY_INT) + call amovkr (1., Memr[wgt], ncols) + + # Loop over median boxes in y. + lp = 0 + lineno = 0 + for (y1 = 1; y1 <= nimlines; y1 = y1 + YMEDIAN(imfit)) { + + lineno = lineno + 1 + current_line = y1 - 1 + y2 = min (y1 + YMEDIAN(imfit) - 1, nimlines) + + # If lines not in range, next image section. + lines_per_box = 0 + while (prl_nextlineno (gl, current_line) != EOF) { + if (current_line > y2) + break + lines_per_box = lines_per_box + 1 + } + if (lines_per_box < (YMEDIAN(imfit) * (MEDIAN_PERCENT(imfit)/100.))) + next + + # Loop over the image lines. + call aclri (Memi[npts], ncols) + do i = y1, y2 { + + # Get image line, and check the good regions list. + lbuf = imgl2r (im, i) + nranges = prl_get_ranges (gl, i, Memi[ranges], max_nranges) + if (nranges == 0) + next + nxpts = is_expand_ranges (Memi[ranges], Memi[colsfit], nimcols) + + # Loop over the median boxes in x. + cp= 0 + mbuf = med + for (x1 = 1; x1 <= nimcols; x1 = x1 + XMEDIAN(imfit)) { + x2 = min (x1 + XMEDIAN(imfit) - 1, nimcols) + ntemp = is_choose_rangesr (Memi[colsfit], Memr[lbuf], + Memr[mbuf+Memi[npts+cp]], nxpts, x1, x2) + Memi[npts+cp] = Memi[npts+cp] + ntemp + mbuf = mbuf + nbox + cp = cp + 1 + } + } + + # Calculate the medians. + nxpts = 0 + mbuf = med + do i = 1, ncols { + if (Memi[npts+i-1] > ((MEDIAN_PERCENT(imfit) / 100.) * nbox)) { + Memr[z+nxpts] = asokr (Memr[mbuf], Memi[npts+i-1], + (Memi[npts+i-1] + 1) / 2) + Memi[cols+nxpts] = i + nxpts = nxpts + 1 + } + mbuf = mbuf + nbox + } + + # Fit the line. + call islfit (sf, Memi[cols], lineno, Memr[z], Memr[wgt], nxpts, + SF_USER, ier) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call eprintf ("Warning: Too few columns to fit line: %d\n") + call pargi (lineno) + case SINGULAR: + call eprintf ("Warning: Solution singular for line: %d\n") + call pargi (lineno) + Memi[lines+lp] = lineno + lp = lp + 1 + default: + Memi[lines+lp] = lineno + lp = lp + 1 + } + } + + # Solve the surface. + call issolve (sf, Memi[lines], lp, ier) + + # Handle fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call error (0, "GOOD_MEDIANS: Cannot fit surface.") + case SINGULAR: + call eprintf ("Warning: Solution singular for surface.") + default: + # everyting OK + } + + # Free space. + call sfree (sp) +end + + +# SET_OUTIMAGE -- Procedure to write an output image of the desired type. + +procedure set_outimage (imin, imout, imfit, sf, rl) + +pointer imin # input image +pointer imout # output image +pointer imfit # pointer to the imsurfut header structure +pointer sf # pointer to the surface descriptor +pointer rl # pointer to the rejected pixel list regions list + +int i, k, ncols, nlines, max_nranges +long u[IM_MAXDIM], v[IM_MAXDIM] +real b1x, b2x, b1y, b2y +pointer sp, x, y, inbuf, outbuf, ranges + +int impnlr(), imgnlr() +real ims_divzero() +extern ims_divzero +errchk malloc, mfree, imgnlr, impnlr + +begin + ncols = IM_LEN(imin,1) + nlines = IM_LEN(imin,2) + max_nranges = ncols + + # Calculate transformation constants from real coordinates to + # median coordinates if median processing specified. + if (MEDIAN(imfit) == YES) { + b1x = (1. + XMEDIAN(imfit)) / (2. * XMEDIAN(imfit)) + b2x = (2. * ncols + XMEDIAN(imfit) - 1.) / (2. * XMEDIAN(imfit)) + b1y = (1. + YMEDIAN(imfit)) / (2. * YMEDIAN(imfit)) + b2y = (2. * nlines + YMEDIAN(imfit) - 1.) / (2. * YMEDIAN(imfit)) + } + + # Allocate space for x coordinates, initialize to image coordinates + # and transform to median coordinates. + call smark (sp) + call salloc (x, ncols, TY_REAL) + call salloc (y, ncols, TY_REAL) + call salloc (ranges, 3 * max_nranges + 1, TY_INT) + + # Intialize the x array. + do i = 1, ncols + Memr[x - 1 + i] = i + if (MEDIAN(imfit) == YES) + call amapr (Memr[x], Memr[x], ncols, 1., real (ncols), b1x, b2x) + + # loop over the images lines + call amovkl (long (1), v, IM_MAXDIM) + call amovkl (long (1), u, IM_MAXDIM) + do i = 1, nlines { + + # Get input and output image buffers. + if (TYPE_OUTPUT(imfit) != FIT) { + if (imgnlr (imin, inbuf, v) == EOF) + call error (0, "Error reading input image.") + } + if (impnlr (imout, outbuf, u) == EOF) + call error (0, "Error writing output image.") + + # Intialize y coordinates to image coordinates, and + # transform to median coordinates. + if (MEDIAN(imfit) == YES) { + Memr[y] = real (i) + call amapr (Memr[y], Memr[y], 1, 1., real (nlines), + b1y, b2y) + call amovkr (Memr[y], Memr[y+1], (ncols-1)) + } else + call amovkr (real (i), Memr[y], ncols) + + # Write output image. + switch (TYPE_OUTPUT(imfit)) { + case FIT: + call isvector (sf, Memr[x], Memr[y], Memr[outbuf], ncols) + case CLEAN: + call clean_line (Memr[x], Memr[y], Memr[inbuf], ncols, nlines, + rl, sf, i, NGROW(imfit)) + call amovr (Memr[inbuf], Memr[outbuf], ncols) + case RESID: + call isvector (sf, Memr[x], Memr[y], Memr[outbuf], ncols) + call asubr (Memr[inbuf], Memr[outbuf], Memr[outbuf], ncols) + case RESP: + call isvector (sf, Memr[x], Memr[y], Memr[outbuf], ncols) + if (IS_INDEF(DIV_MIN(imfit))) { + iferr (call adivr (Memr[inbuf], Memr[outbuf], Memr[outbuf], + ncols)) + call advzr (Memr[inbuf], Memr[outbuf], Memr[outbuf], + ncols, ims_divzero) + } else { + do k = 1, ncols { + if (Memr[outbuf-1+k] < DIV_MIN(imfit)) + Memr[outbuf-1+k] = 1. + else + Memr[outbuf-1+k] = Memr[inbuf-1+k] / + Memr[outbuf-1+k] + } + } + default: + call error (0, "SET_OUTIMAGE: Unknown output type.") + } + } + + # Free space + call sfree (sp) +end + + +# CLEAN_LINE -- Procedure to set weights of rejected points to zero + +procedure clean_line (x, y, z, ncols, nlines, rl, sf, line, ngrow) + +real x[ARB] # array of weights set to 1 +real y # y value of line +real z[ARB] # line of data +int ncols # number of image columns +int nlines # number of image lines +pointer rl # pointer to reject pixel list +pointer sf # surface fitting +int line # line number +int ngrow # radius for region growing + +int cp, j, k, nranges, dist, yreg_min, yreg_max, xreg_min, xreg_max +pointer sp, branges +real r2 +int prl_get_ranges(), is_next_number() +real iseval() + +begin + call smark (sp) + call salloc (branges, 3 * ncols + 1, TY_INT) + + r2 = ngrow ** 2 + yreg_min = max (1, line - ngrow) + yreg_max = min (nlines, line + ngrow) + + do j = yreg_min, yreg_max { + nranges = prl_get_ranges (rl, j, Memi[branges], ncols) + if (nranges == 0) + next + dist = int (sqrt (r2 - (j - line) ** 2)) + cp = 0 + while (is_next_number (Memi[branges], cp) != EOF) { + xreg_min = max (1, cp - dist) + xreg_max = min (ncols, cp + dist) + do k = xreg_min, xreg_max + z[k] = iseval (sf, x[k], y) + cp = xreg_max + } + } + + call sfree (sp) +end + + +# DO_REJECT -- Procedure to detect rejected pixels in an image. + +procedure do_reject (im, imfit, gl, sf, rl) + +pointer im # pointer to in put image +pointer imfit # pointer to image fitting structure +pointer gl # pointer to good regions list +pointer sf # pointer to surface descriptor +pointer rl # pointer to rejected pixel list + +int niter, nrejects +real sigma +int detect_rejects() +real get_sigma() +errchk prl_init, detect_rejects, get_sigma, refit_surface + +begin + # Initialize rejected pixel list. + call prl_init (rl, int(IM_LEN(im,1)), int(IM_LEN(im,2))) + + # Do an iterative rejection cycle on the image. + niter = 0 + repeat { + + # Get the sigma of the fit. + sigma = get_sigma (im, gl, sf, rl) + + # Detect rejected pixels. + nrejects = detect_rejects (im, imfit, gl, sf, rl, sigma) + + # If no rejected pixels quit, else refit surface. + if (nrejects == 0 || NITER(imfit) == 0) + break + call refit_surface (im, imfit, gl, sf, rl) + + niter = niter + 1 + + } until (niter == NITER(imfit)) +end + + +# REFIT_SURFACE -- Procedure tp refit the surface. + +procedure refit_surface (im, imfit, gl, sf, rl) + +pointer im # pointer to image +pointer imfit # pointer to surface fitting structure +pointer gl # pointer to good regions list +pointer sf # pointer to surface descriptor +pointer rl # pointer to rejected pixels list + +int i, ijunk, lp, ier, max_nranges +int ncols, nlines, npts, nfree, nrejects, nranges, ncoeff +pointer sp, cols, colsfit, lines, buf, fbuf, wgt, granges + +int prl_get_ranges(), grow_regions(), is_expand_ranges() +int is_choose_rangesr() +pointer imgl2r() +errchk smark, salloc, sfree, imgl2r +errchk iscoeff, islfit, issolve +errchk prl_get_ranges, grow_regions +errchk is_choose_rangesr + +begin + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + max_nranges = ncols + + # Allocate up temporary storage. + call smark (sp) + call salloc (cols, ncols, TY_INT) + call salloc (colsfit, ncols, TY_INT) + call salloc (lines, nlines, TY_INT) + call salloc (fbuf, ncols, TY_REAL) + call salloc (wgt, ncols, TY_REAL) + call salloc (granges, 3 * max_nranges + 1, TY_INT) + + # Initialize columns. + do i = 1, ncols + Memi[cols+i-1] = i + call amovi (Memi[cols], Memi[colsfit], ncols) + + # Get number of coefficients. + switch (SURFACE_TYPE(imfit)) { + case SF_LEGENDRE, SF_CHEBYSHEV: + ncoeff = XORDER(imfit) + case SF_SPLINE3: + ncoeff = XORDER(imfit) + 3 + case SF_SPLINE1: + ncoeff = XORDER(imfit) + 1 + } + + # Refit affected lines and solve for surface. + lp = 0 + do i = 1, nlines { + + # Determine whether image line is good. + if (gl != NULL) { + nranges = prl_get_ranges (gl, i, Memi[granges], max_nranges) + if (nranges == 0) + next + } + + # Define rejected points with region growing. + call amovkr (1., Memr[wgt], ncols) + nrejects = grow_regions (Memr[wgt], ncols, nlines, rl, i, + NGROW(imfit)) + + # Get number of data points. + if (gl == NULL) + npts = ncols + else + npts = is_expand_ranges (Memi[granges], Memi[colsfit], ncols) + nfree = npts - nrejects + + # If no rejected pixels skip to next line. + if (nrejects == 0) { + if (nfree >= ncoeff ) { + Memi[lines+lp] = i + lp = lp + 1 + } + next + } + + # Read in image line. + buf = imgl2r (im, i) + if (buf == EOF) + call error (0, "REFIT_SURFACE: Error reading image.") + + # Select the data. + if (gl == NULL) { + npts = ncols + if (nfree >= ncoeff) + call islfit (sf, Memi[colsfit], i, Memr[buf], Memr[wgt], + npts, SF_USER, ier) + else + ier = NO_DEG_FREEDOM + } else { + ijunk = is_choose_rangesr (Memi[colsfit], Memr[buf], + Memr[fbuf], npts, 1, ncols) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[wgt], Memr[wgt], + npts, 1, ncols) + if (nfree >= ncoeff) + call islfit (sf, Memi[colsfit], i, Memr[fbuf], Memr[wgt], + npts, SF_USER, ier) + else + ier = NO_DEG_FREEDOM + } + + # Evaluate fitting errors. + switch (ier) { + case NO_DEG_FREEDOM: + call eprintf ("REFIT_SURFACE: Too few points to fit line: %d\n") + call pargi (i) + case SINGULAR: + call eprintf ("REFIT_SURFACE: Solution singular for line: %d\n") + call pargi (i) + Memi[lines+lp] = i + lp = lp + 1 + default: + Memi[lines+lp] = i + lp = lp + 1 + } + } + + # Resolve surface. + call issolve (sf, Memi[lines], lp, ier) + + # Evaluate fitting errors for surface. + switch (ier) { + case NO_DEG_FREEDOM: + call error (0, "REFIT_SURFACE: Too few points to fit surface\n") + case SINGULAR: + call eprintf ("REFIT_SURFACE: Solution singular for surface\n") + default: + # everything OK + } + + call sfree (sp) + +end + + +# GROW_REGIONS -- Procedure to set weights of rejected points to zero. + +int procedure grow_regions (wgt, ncols, nlines, rl, line, ngrow) + +real wgt[ARB] # array of weights set to 1 +int ncols # number of image columnspoints +int nlines # number of images lines +pointer rl # pointer to reject pixel list +int line # line number +int ngrow # radius for region growing + +int cp, j, k, nrejects, nranges, max_nranges +int dist, yreg_min, yreg_max, xreg_min, xreg_max +pointer sp, branges +real r2 +int prl_get_ranges(), is_next_number() +errchk smark, salloc, sfree +errchk prl_get_ranges, is_next_number + +begin + max_nranges = ncols + + call smark (sp) + call salloc (branges, 3 * max_nranges + 1, TY_INT) + + r2 = ngrow ** 2 + nrejects = 0 + yreg_min = max (1, line - ngrow) + yreg_max = min (nlines, line + ngrow) + + do j = yreg_min, yreg_max { + nranges = prl_get_ranges (rl, j, Memi[branges], max_nranges) + if (nranges == 0) + next + dist = int (sqrt (r2 - (j - line) ** 2)) + cp = 0 + while (is_next_number (Memi[branges], cp) != EOF) { + xreg_min = max (1, cp - dist) + xreg_max = min (ncols, cp + dist) + do k = xreg_min, xreg_max { + if (wgt[k] > 0.) { + wgt[k] = 0. + nrejects = nrejects + 1 + } + } + cp = xreg_max + } + } + + call sfree (sp) + return (nrejects) +end + + +# GET_SIGMA -- Procedure to calculate the sigma of the surface fit + +real procedure get_sigma (im, gl, sf, rl) + +pointer im # pointer to image +pointer gl # pointer to good pixel list +pointer sf # pointer to surface deascriptor +pointer rl # pointer to rejected pixel list + +int i, ijunk, cp, nranges, npts, ntpts, ncols, nlines, max_nranges +pointer sp, colsfit, x, xfit, y, zfit, buf, fbuf, wgt, granges, branges +real sum, sigma +int prl_get_ranges(), is_next_number(), is_expand_ranges() +int is_choose_rangesr() +pointer imgl2r() +real asumr(), awssqr() +errchk smark, salloc, sfree, imgl2r + +begin + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + max_nranges = ncols + + # Allocate working space. + call smark (sp) + call salloc (colsfit, ncols, TY_INT) + call salloc (x, ncols, TY_REAL) + call salloc (xfit, ncols, TY_REAL) + call salloc (y, ncols, TY_REAL) + call salloc (fbuf, ncols, TY_REAL) + call salloc (zfit, ncols, TY_REAL) + call salloc (wgt, ncols, TY_REAL) + call salloc (granges, 3 * max_nranges + 1, TY_INT) + call salloc (branges, 3 * max_nranges + 1, TY_INT) + + # Intialize the x array. + do i = 1, ncols + Memr[x+i-1] = i + call amovr (Memr[x], Memr[xfit], ncols) + + sum = 0. + sigma = 0. + ntpts = 0 + + # Loop over the image. + do i = 1, nlines { + + # Check that line is in range. + if (gl != NULL) { + nranges = prl_get_ranges (gl, i, Memi[granges], max_nranges) + if (nranges == 0) + next + npts = is_expand_ranges (Memi[granges], Memi[colsfit], ncols) + } + + # Read in image. + buf = imgl2r (im, i) + if (buf == EOF) + call error (0, "GET_SIGMA: Error reading image.") + + # Select appropriate data and fit. + call amovkr (real (i), Memr[y], ncols) + if (gl == NULL) { + npts = ncols + call isvector (sf, Memr[xfit], Memr[y], Memr[zfit], npts) + call asubr (Memr[buf], Memr[zfit], Memr[zfit], npts) + } else { + ijunk = is_choose_rangesr (Memi[colsfit], Memr[x], Memr[xfit], + npts, 1, ncols) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[buf], Memr[fbuf], + npts, 1, ncols) + call isvector (sf, Memr[xfit], Memr[y], Memr[zfit], npts) + call asubr (Memr[fbuf], Memr[zfit], Memr[zfit], npts) + } + + # Get ranges of rejected pixels for the line and set weights. + call amovkr (1., Memr[wgt], ncols) + nranges = prl_get_ranges (rl, i, Memi[branges], max_nranges) + if (nranges > 0) { + cp = 0 + while (is_next_number (Memi[branges], cp) != EOF) + Memr[wgt+cp-1] = 0. + if (gl != NULL) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[wgt], + Memr[wgt], npts, 1, ncols) + } + + # Calculate sigma. + sigma = sigma + awssqr (Memr[zfit], Memr[wgt], npts) + ntpts = ntpts + asumr (Memr[wgt], npts) + } + + call sfree (sp) + + return (sqrt (sigma / (ntpts - 1))) +end + + +# DETECT_REJECTS - Procedure to detect rejected pixels. + +int procedure detect_rejects (im, imfit, gl, sf, rl, sigma) + +pointer im # pointer to image +pointer imfit # pointer to surface fitting structure +pointer gl # pointer to good pixel list +pointer sf # pointer to surface descriptor +pointer rl # pointer to rejected pixel list +real sigma # standard deviation of fit + +int i, j, ijunk, cp, ncols, nlines, npts, nranges, nlrejects, ntrejects +int norejects, max_nranges +pointer sp, granges, branges, x, xfit, cols, colsfit, y, zfit, buf, fbuf +pointer wgt, list +real upper, lower + +int prl_get_ranges(), is_next_number(), is_make_ranges(), is_expand_ranges() +int is_choose_rangesr() +pointer imgl2r() + +begin + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + max_nranges = ncols + + # Allocate temporary space. + call smark (sp) + call salloc (x, ncols, TY_REAL) + call salloc (xfit, ncols, TY_REAL) + call salloc (cols, ncols, TY_INT) + call salloc (colsfit, ncols, TY_INT) + call salloc (y, ncols, TY_REAL) + call salloc (fbuf, ncols, TY_REAL) + call salloc (zfit, ncols, TY_REAL) + call salloc (wgt, ncols, TY_REAL) + call salloc (granges, 3 * max_nranges + 1, TY_INT) + call salloc (branges, 3 * max_nranges + 1, TY_INT) + call salloc (list, ncols, TY_INT) + + # Intialize x and column values. + do i = 1, ncols { + Memi[cols+i-1] = i + Memr[x+i-1] = i + } + call amovr (Memr[x], Memr[xfit], ncols) + call amovi (Memi[cols], Memi[colsfit], ncols) + + ntrejects = 0 + if (LOWER(imfit) <= 0.0) + lower = -MAX_REAL + else + lower = -sigma * LOWER(imfit) + if (UPPER(imfit) <= 0.0) + upper = MAX_REAL + else + upper = sigma * UPPER(imfit) + + # Loop over the image. + do i = 1, nlines { + + # Get ranges if appropriate. + if (gl != NULL) { + nranges = prl_get_ranges (gl, i, Memi[granges], max_nranges) + if (nranges == 0) + next + npts = is_expand_ranges (Memi[granges], Memi[colsfit], ncols) + } + + # Read in image. + buf = imgl2r (im, i) + if (buf == EOF) + call error (0, "GET_SIGMA: Error reading image.") + + # Select appropriate data and fit. + call amovkr (real (i), Memr[y], ncols) + if (gl == NULL) { + npts = ncols + call isvector (sf, Memr[xfit], Memr[y], Memr[zfit], npts) + call asubr (Memr[buf], Memr[zfit], Memr[zfit], npts) + } else { + ijunk = is_choose_rangesr (Memi[colsfit], Memr[x], Memr[xfit], + npts, 1, ncols) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[buf], Memr[fbuf], + npts, 1, ncols) + call isvector (sf, Memr[xfit], Memr[y], Memr[zfit], npts) + call asubr (Memr[fbuf], Memr[zfit], Memr[zfit], npts) + } + + # Get ranges of rejected pixels for the line and set weights. + call amovkr (1., Memr[wgt], ncols) + nranges = prl_get_ranges (rl, i, Memi[branges], max_nranges) + norejects = 0 + if (nranges > 0) { + cp = 0 + while (is_next_number (Memi[branges], cp) != EOF) { + Memi[list+norejects] = cp + norejects = norejects + 1 + Memr[wgt+cp-1] = 0. + } + if (gl != NULL) + ijunk = is_choose_rangesr (Memi[colsfit], Memr[wgt], + Memr[wgt], npts, 1, ncols) + } + + # Detect deviant pixels. + nlrejects = 0 + do j = 1, npts { + if ((Memr[zfit+j-1] < lower || Memr[zfit+j-1] > upper) && + Memr[wgt+j-1] != 0.) { + Memi[list+norejects+nlrejects] = Memi[colsfit+j-1] + nlrejects = nlrejects + 1 + } + } + + # Add to rejected pixel list. + if (nlrejects > 0) { + call asrti (Memi[list], Memi[list], norejects + nlrejects) + nranges = is_make_ranges (Memi[list], norejects + nlrejects, + Memi[granges], max_nranges) + call prl_put_ranges (rl, i, i, Memi[granges]) + } + + ntrejects = ntrejects + nlrejects + } + + call sfree (sp) + return (ntrejects) +end + + +# AWSSQR -- Procedure to calculate the weighted sum of the squares + +real procedure awssqr (a, w, npts) + +real a[npts] # array of data +real w[npts] # array of points +int npts # number of data points + +int i +real sum + +begin + sum = 0. + do i = 1, npts + sum = sum + w[i] * a[i] ** 2 + + return (sum) +end + + +# IMS_DIVZER0 -- Return 1. on a divide by zero + +real procedure ims_divzero (x) + +real x + +begin + return (1.) +end diff --git a/pkg/images/imfit/src/mkpkg b/pkg/images/imfit/src/mkpkg new file mode 100644 index 00000000..3bc27b8f --- /dev/null +++ b/pkg/images/imfit/src/mkpkg @@ -0,0 +1,15 @@ +# Library for the IMAGES IMFIT Subpackage Tasks + +$checkout libpkg.a ../../ +$update libpkg.a +$checkin libpkg.a ../../ +$exit + +libpkg.a: + fit1d.x <imhdr.h> <pkg/gtools.h> <error.h> + imsurfit.x imsurfit.h <math/surfit.h> <imhdr.h> <mach.h> + pixlist.x pixlist.h + ranges.x <ctype.h> <mach.h> + t_imsurfit.x imsurfit.h <error.h> <imhdr.h> + t_lineclean.x <imhdr.h> <pkg/gtools.h> + ; diff --git a/pkg/images/imfit/src/pixlist.h b/pkg/images/imfit/src/pixlist.h new file mode 100644 index 00000000..39c875a9 --- /dev/null +++ b/pkg/images/imfit/src/pixlist.h @@ -0,0 +1,11 @@ +# PIXEL LIST descriptor structure + +define LEN_PLSTRUCT 10 + +define PRL_NCOLS Memi[$1] # number of columns +define PRL_NLINES Memi[$1+1] # number of lines +define PRL_LINES Memi[$1+2] # pointer to the line offsets +define PRL_LIST Memi[$1+3] # pointer to list of ranges +define PRL_SZLIST Memi[$1+4] # size of list in INTS +define PRL_LP Memi[$1+5] # offset to next space in list + diff --git a/pkg/images/imfit/src/pixlist.x b/pkg/images/imfit/src/pixlist.x new file mode 100644 index 00000000..066637fd --- /dev/null +++ b/pkg/images/imfit/src/pixlist.x @@ -0,0 +1,369 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "pixlist.h" + +.help pixels xtools "Pixel List Handling Tools" +.nf ________________________________________________________________________ +.fi +.ih +PURPOSE +These routines provide simple pixel list handling facilities and are +intended as a temporary facility pending full scale completion of +image masking. The list is stored in the form of ranges as a function +of line number. Each image line has a offset which may be NULL for +no entry or an offset into the list itself. The actual list is a set of +ranges with the ranges for each line delimited by a NULL. Routines +exist to fetch the ranges for a given line, add or append ranges to a +given line, fetch the next or previous line number with a non-NULL +range and specify whether two lines have the same ranges. At present +the list can grow indefinitely, with additional memory being added as +necessary. No attempt is made to clean up redundant entries though +such a faclity could easily be added. The ranges arguments conform +with the design of the ranges routinesr, with each range consisting +of and intitial and final entry and a step size. A list of ranges +is terminated with a NULL +.ih +PROCEDURE +.nf +prl_init (pl, ncols, nlines) + + pointer pl # pointer to list descriptor + int ncols # number of image columns + int nlines # number of image lines + +nranges = prl_get_ranges (pl, lineno, ranges, max_nranges) + + pointer pl # pointer to list descriptor + int lineno # line number of ranges to be fetched + int ranges[ARB] # ranges to be output + int max_nranges # the maximum number of ranges to be output + +prl_put_ranges (pl, linemin, linemax, ranges) + + pointer pl # pointer to list descriptor + int linemin # minimum line number + int linemax # maximum line number + int ranges[ARB] # ranges to be added to list + +prl_append_ranges (pl, linemin, linemax, ranges) + + pointer pl # pointer to list descriptor + int linemin # minimum line number + int linemax # maximum line number + int ranges[ARB] # ranges to be added to list + +next_lineno/EOF = prl_nextlineno (pl, current_lineno) + + pointer pl # pointer to list descriptor + int current_lineno # current line number + +prev_lineno/EOF = prl_prevlineno (pl, current_lineno) + + pointer pl # pointer to the list descriptor + int current_lineno # current line number + +YES/NO = prl_eqlines (pl, line1, line2) + + pointer pl # pointer to the list descriptor + int line1 # first line number + int line2 # second line number + +prl_free (pl) + + pointer pl # pointer to list descriptor +.fi +.endhelp ________________________________________________________________ + + +# PRL_ADD_RANGES -- Procedure to add the ranges for a given range of +# line numbers to the pixel list. The new ranges will be appended to any +# previously existing ranges for the specified line numbers. + +procedure prl_add_ranges (pl, linemin, linemax, ranges) + +pointer pl # pointer to the list descriptor +int linemin # minimum line number +int linemax # maximum line number +int ranges[ARB] # ranges + +int i, j, lc +int olp, lp, lnull, lold +int nr, nnewr, noldr + +begin + # check conditions + if ((linemin < 1) || (linemax > PRL_NLINES(pl)) || linemin > linemax) + return + + # calculate the length of the range to be appended minus the null + nr = 0 + while (ranges[nr+1] != NULL) + nr = nr + 1 + + + lc = 1 + olp = -1 + do i = linemin, linemax { + + # get offset for line i + lp = Memi[PRL_LINES(pl)+i-1] + + # if line pointer is undefined + if (lp == NULL) { + + if (lc == 1) { + + # set line pointer and store + Memi[PRL_LINES(pl)+i-1] = PRL_LP(pl) + lnull = PRL_LP(pl) + + # check the size of the list + if (PRL_SZLIST(pl) < (nr + PRL_LP(pl))) { + PRL_SZLIST(pl) = PRL_SZLIST(pl) + nr + 1 + call realloc (PRL_LIST(pl), PRL_SZLIST(pl), TY_INT) + } + + # move ranges and reset pointers + call amovi (ranges, Memi[PRL_LIST(pl)+PRL_LP(pl)-1], nr) + PRL_LP(pl) = PRL_LP(pl) + nr + 1 + Memi[PRL_LIST(pl)+PRL_LP(pl)-2] = NULL + lc = lc + 1 + + } else + + # set line pointer + Memi[PRL_LINES(pl)+i-1] = lnull + + } else { + + if (lp != olp) { + + # set line pointer and store + Memi[PRL_LINES(pl)+i-1] = PRL_LP(pl) + lold = PRL_LP(pl) + + # find length of previously defined range and calculate + # length of new ranges + for (j = lp; Memi[PRL_LIST(pl)+j-1] != NULL; j = j + 1) + ; + noldr = j - lp + nnewr = noldr + nr + + # check size of list + if (PRL_SZLIST(pl) < (nnewr + PRL_LP(pl))) { + PRL_SZLIST(pl) = PRL_SZLIST(pl) + nnewr + 1 + call realloc (PRL_LIST(pl), PRL_SZLIST(pl), TY_INT) + } + + # add ranges to list and update pointers + call amovi (Memi[PRL_LIST(pl)+lp-1], + Memi[PRL_LIST(pl)+PRL_LP(pl)-1], noldr) + PRL_LP(pl) = PRL_LP(pl) + noldr + call amovi (ranges, Memi[PRL_LIST(pl)+PRL_LP(pl)-1], nr) + PRL_LP(pl) = PRL_LP(pl) + nr + 1 + Memi[PRL_LIST(pl)+PRL_LP(pl)-2] = NULL + + } else + + # set line pointers + Memi[PRL_LINES(pl)+i-1] = lold + + olp = lp + } + } + +end + +# PRL_EQLINES -- Routine to test whether two lines have equal ranges. +# The routine returns YES or NO. + +int procedure prl_eqlines (pl, line1, line2) + +pointer pl # pointer to the list +int line1 # line numbers +int line2 + +begin + if (Memi[PRL_LINES(pl)+line1-1] == Memi[PRL_LINES(pl)+line2-1]) + return (YES) + else + return (NO) +end + +# PRL_GET_RANGES -- Procedure to fetch the ranges for the specified lineno. +# Zero is returned if there are no ranges otherwise the number of ranges +# are returned. The ranges are stored in an integer array. Three positive +# numbers are used to define a range a minimum, maximum and a step size. +# The ranges are delimited by a NULL. + +int procedure prl_get_ranges (pl, lineno, ranges, max_nranges) + +pointer pl # pointer to the pixel list descriptor +int lineno # line number +int ranges[ARB] # array of ranges +int max_nranges # the maximum number of ranges + +int lp, ip +int nranges + +begin + # check for existence of ranges + if (Memi[PRL_LINES(pl)+lineno-1] == NULL) { + ranges[1] = NULL + return (0) + } + + # set pointer to the first element in list for line lineno + lp = PRL_LIST(pl) + Memi[PRL_LINES(pl)+lineno-1] - 1 + + # get ranges + nranges = 0 + ip = 1 + while (Memi[lp+ip-1] != NULL && nranges <= 3 * max_nranges) { + ranges[ip] = Memi[lp+ip-1] + ip = ip + 1 + nranges = nranges + 1 + } + ranges[ip] = NULL + + # return nranges + if (nranges == 0) + return (nranges) + else + return (nranges / 3) +end + +# PRL_NEXTLINENO -- Procedure to fetch the next line number with a set of +# defined ranges given the current line number. Note that the current +# line number is updated. + +int procedure prl_nextlineno (pl, current_lineno) + +pointer pl # pointer to the pixel list descriptor +int current_lineno # current line number + +int findex, lp + +begin + findex = max (1, current_lineno + 1) + do lp = findex, PRL_NLINES(pl) { + if (Memi[PRL_LINES(pl)+lp-1] != NULL) { + current_lineno = lp + return (lp) + } + } + + return (EOF) +end + +# PRL_PREVLINENO -- Procedure to fetch the first previous line number +# with a set of defined ranges given the current line number. +# Note that the current line number is updated. + +int procedure prl_prevlineno (pl, current_lineno) + +pointer pl # pointer to the pixel list descriptor +int current_lineno # current line number + +int findex, lp + +begin + findex = min (current_lineno - 1, PRL_NLINES(pl)) + do lp = findex, 1, -1 { + if (Memi[PRL_LINES(pl)+lp-1] != NULL) { + current_lineno = lp + return (lp) + } + } + + return (EOF) +end + +# PRL_PUT_RANGES -- Procedure to add the ranges for a given range of +# lines to the pixel list. Note that any previously defined ranges are +# lost. + +procedure prl_put_ranges (pl, linemin, linemax, ranges) + +pointer pl # pointer to the list +int linemin # minimum line +int linemax # maximum line +int ranges[ARB] # list of ranges + +int i +int len_range + +begin + # check boundary conditions + if ((linemin < 1) || (linemax > PRL_NLINES(pl)) || (linemin > linemax)) + return + + # determine length of range string minus the NULL + len_range = 0 + while (ranges[len_range+1] != NULL) + len_range = len_range + 1 + + # check space allocation + if (PRL_SZLIST(pl) < (len_range + PRL_LP(pl))) { + PRL_SZLIST(pl) = PRL_SZLIST(pl) + len_range + 1 + call realloc (PRL_LIST(pl), PRL_SZLIST(pl), TY_INT) + } + + # set the line pointers + do i = linemin, linemax + Memi[PRL_LINES(pl)+i-1] = PRL_LP(pl) + + # add ranges + call amovi (ranges, Memi[PRL_LIST(pl)+PRL_LP(pl)-1], len_range) + PRL_LP(pl) = PRL_LP(pl) + len_range + 1 + Memi[PRL_LIST(pl)+PRL_LP(pl)-2] = NULL +end + + +# PLR_FREE -- Procedure to free the pixel list descriptor + +procedure prl_free (pl) + +pointer pl # pointer to pixel list descriptor + +begin + if (pl == NULL) + return + + if (PRL_LIST(pl) != NULL) + call mfree (PRL_LIST(pl), TY_INT) + if (PRL_LINES(pl) != NULL) + call mfree (PRL_LINES(pl), TY_INT) + + call mfree (pl, TY_STRUCT) +end + +# PRL_INIT -- Procedure to initialize the pixel list. Ncols and nlines are +# the number of columns and lines respectively in the associated IRAF +# image. + +procedure prl_init (pl, ncols, nlines) + +pointer pl # pixel list descriptor +int ncols # number of image columns +int nlines # number of image lines + +begin + # allocate space for a pixel list descriptor + call malloc (pl, LEN_PLSTRUCT, TY_STRUCT) + + # initialize + PRL_NCOLS(pl) = ncols + PRL_NLINES(pl) = nlines + + # allocate space for the line pointers + call malloc (PRL_LINES(pl), PRL_NLINES(pl), TY_INT) + call amovki (NULL, Memi[PRL_LINES(pl)], PRL_NLINES(pl)) + + # set pointer to next free element + PRL_LP(pl) = 1 + + # allocate space for the actual list + call malloc (PRL_LIST(pl), PRL_NLINES(pl), TY_INT) + PRL_SZLIST(pl) = PRL_NLINES(pl) +end diff --git a/pkg/images/imfit/src/ranges.x b/pkg/images/imfit/src/ranges.x new file mode 100644 index 00000000..19dc5c0e --- /dev/null +++ b/pkg/images/imfit/src/ranges.x @@ -0,0 +1,524 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <ctype.h> + +.help ranges xtools "Range Parsing Tools" +.ih +PURPOSE + +These tools +parse a string using a syntax to represent integer values, ranges, and +steps. The parsed string is used to generate a list of integers for various +purposes such as specifying lines or columns in an image or tape file numbers. +.ih +SYNTAX + +The syntax for the range string consists of positive integers, '-' (minus), +'x', ',' (comma), and whitespace. The commas and whitespace are ignored +and may be freely used for clarity. The remainder of the string consists +of sequences of five fields. The first field is the beginning of a range, +the second is a '-', the third is the end of the range, the fourth is +a 'x', and the fifth is a step size. Any of the five fields may be +missing causing various default actions. The defaults are illustrated in +the following table. + +.nf +-3x1 A missing starting value defaults to 1. +2-x1 A missing ending value defaults to MAX_INT. +2x1 A missing ending value defaults to MAX_INT. +2-4 A missing step defaults to 1. +4 A missing ending value and step defaults to an ending + value equal to the starting value and a step of 1. +x2 Missing starting and ending values defaults to + the range 1 to MAX_INT with the specified step. +"" The null string is equivalent to "1 - MAX_INT x 1", + i.e all positive integers. +.fi + +The specification of several ranges yields the union of the ranges. +.ih +EXAMPLES + +The following examples further illustrate the range syntax. + +.nf +- All positive integers. +1,5,9 A list of integers equivalent to 1-1x1,5-5x1,9-9x1. +x2 Every second positive integer starting with 1. +2x3 Every third positive integer starting with 2. +-10 All integers between 1 and 10. +5- All integers greater than or equal to 5. +9-3x1 The integers 3,6,9. +.fi +.ih +PROCEDURES + +.ls 4 is_decode_ranges + +.nf +int procedure is_decode_ranges (range_string, ranges, max_ranges, minimum, + maximum, 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 minimum, maximum # Minimum and maximum range values allowed +int nvalues # The number of values in the ranges +.fi + +The range string is decoded into an integer array of maximum dimension +3 * max_ranges. Each range consists of three consecutive integers +corresponding to the starting and ending points of the range and the +step size. The number of integers covered by the ranges is returned +as nvalue. The end of the set of ranges is marked by a NULL. +The returned status is either ERR or OK. +.le +.ls 4 is_next_number, is_previous_number + +.nf +int procedure is_next_number (ranges, number) +int procedure is_previous_number (ranges, number) + +int ranges[ARB] # Range array +int number # Both input and output parameter +.fi + +Given a value for number the procedures find the next (previous) number in +increasing (decreasing) +value within the set of ranges. The next (previous) number is returned in +the number argument. A returned status is either OK or EOF. +EOF indicates that there are no greater values. The usual usage would +be in a loop of the form: + +.nf + number = 0 + while (is_next_number (ranges, number) != EOF) { + <Statements using number> + } +.fi +.le +.ls 4 is_in_rangelist + +.nf +bool procedure is_in_rangelist (ranges, number) + +int ranges[ARB] # Ranges array +int number # Number to check againts ranges +.fi + +A boolean value is returned indicating whether number is covered by +the ranges. + +.endhelp + + +# IS_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 is_decode_ranges (range_string, ranges, max_ranges, minimum, + maximum, 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 minimum, maximum # Minimum and maximum range values allowed +int nvalues # The number of values in the ranges + +int ip, nrange, out_of_range, a, b, first, last, step, ctoi() + +begin + ip = 1 + nrange = 1 + nvalues = 0 + out_of_range = 0 + + while (nrange < max_ranges) { + # Default values + a = minimum + b = maximum + step = 1 + + # 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) { + if (out_of_range == 0) { + # Null string defaults + ranges[1, 1] = a + ranges[2, 1] = b + ranges[3, 1] = step + ranges[1, 2] = NULL + nvalues = (b - a) / step + 1 + return (OK) + } else { + # Only out of range data + return (ERR) + } + } else { + ranges[1, nrange] = NULL + return (OK) + } + } else if (range_string[ip] == '-') + ; + else if (range_string[ip] == '*') + ; + else if (range_string[ip] == 'x') + ; + else if (IS_DIGIT(range_string[ip])) { # ,n.. + if (ctoi (range_string, ip, a) == 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 b = a. + if (range_string[ip] == 'x') + ; + else if ((range_string[ip] == '-') || (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, b) == 0) + return (ERR) + } else if (range_string[ip] == 'x') + ; + else + return (ERR) + } else + b = a + + # 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 if (range_string[ip] == '*') + ; + else + return (ERR) + } + + # Output the range triple. + first = min (a, b) + last = max (a, b) + if (first < minimum) + first = minimum + mod (step - mod (minimum - first, step), step) + if (last > maximum) + last = maximum - mod (last - maximum, step) + if (first <= last) { + ranges[1, nrange] = first + ranges[2, nrange] = last + ranges[3, nrange] = step + nvalues = nvalues + (last - first) / step + 1 + nrange = nrange + 1 + } else + out_of_range = out_of_range + 1 + } + + return (ERR) # ran out of space +end + + +# IS_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 is_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 = ranges[ip] + last = 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 + + +# IS_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 is_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 = ranges[ip] + last = 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_RANGELLIST -- Test number to see if it is in range. + +bool procedure is_in_rangelist (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 = ranges[ip] + last = ranges[ip+1] + step = ranges[ip+2] + if (number >= first && number <= last) + if (mod (number - first, step) == 0) + return (TRUE) + } + + return (FALSE) +end + + +# IS_EXPAND_RANGES -- Expand a range string into a array of values. + +int procedure is_expand_ranges (ranges, array, max_nvalues) + +int ranges[ARB] # Range array +int array[max_nvalues] # Array of values +int max_nvalues # Maximum number of values + +int n, value + +int is_next_number() + +begin + n = 0 + value = 0 + while ((n < max_nvalues) && (is_next_number (ranges, value) != EOF)) { + n = n + 1 + array[n] = value + } + + return (n) +end + + +# IS_SELECT_RANGES -- Select array values in the ranges. +# The input and output arrays may be the same. + +procedure is_select_ranges (a, b, ranges) + +real a[ARB] # Input array +real b[ARB] # Output array +int ranges[3, ARB] # Ranges + +int i, j, npts, nmove + +begin + npts = 0 + for (i = 1; ranges[1, i] != NULL; i = i + 1) { + if (ranges[3, i] == 1) { + nmove = ranges[2, i] - ranges[1, i] + 1 + call amovr (a[ranges[1, i]], b[npts + 1], nmove) + npts = npts + nmove + } else { + do j = ranges[1, i], ranges[2, i], ranges[3, i] { + npts = npts + 1 + b[npts] = a[j] + } + } + } +end + + +# IS_CHOOSE_RANGESI -- Copy the selected values from array a to b. + +int procedure is_choose_rangesi (indices, a, b, npts, ifirst, ilast) + +int indices[ARB] # array of indices +int a[ARB] # input array +int b[ARB] # output array +int npts # number of points +int ifirst # first index +int ilast # last index + +int i, element + +begin + element = 1 + do i = 1, npts { + if (indices[i] < ifirst || indices[i] > ilast) + next + b[element] = a[indices[i]] + element = element + 1 + } + return (element - 1) +end + + +# IS_CHOOSE_RANGESR -- Copy the selected values from array a to b. + +int procedure is_choose_rangesr (indices, a, b, npts, ifirst, ilast) + +int indices[ARB] # array of indices +real a[ARB] # input array +real b[ARB] # output array +int npts # number of points +int ifirst # first element to be extracted +int ilast # last element to be extracted + +int i, element + +begin + element = 1 + do i = 1, npts { + if (indices[i] < ifirst || indices[i] > ilast) + next + b[element] = a[indices[i]] + element = element + 1 + } + return (element - 1) +end + + +# IS_MAKE_RANGES -- Procedure to make a set of ranges from an ordered list +# of column numbers. Only a step size of 1 is checked for. + +int procedure is_make_ranges (list, npts, ranges, max_nranges) + +int list[ARB] # list of column numbers in increasing order +int npts # number of list elements +int ranges[ARB] # output ranges +int max_nranges # the maximum number of ranges + +bool next_range +int ip, op, nranges + +begin + # If zero list elements return + if (npts == 0) { + ranges[1] = NULL + return (0) + } + + # Initialize + nranges = 0 + ranges[1] = list[1] + op = 2 + next_range = false + + # Loop over column list + for (ip = 2; ip <= npts && nranges < max_nranges; ip = ip + 1) { + if ((list[ip] != (list[ip-1] + 1))) { + ranges[op] = list[ip-1] + op = op + 1 + ranges[op] = 1 + op = op + 1 + nranges = nranges + 1 + ranges[op] = list[ip] + op = op + 1 + } + } + + # finish off + if (npts == 1) { + ranges[op] = list[npts] + ranges[op+1] = 1 + ranges[op+2] = NULL + nranges = 1 + } else if (nranges == max_nranges) { + ranges[op-1] = NULL + } else { + ranges[op] = list[npts] + ranges[op+1] = 1 + ranges[op+2] = NULL + nranges = nranges + 1 + } + + return (nranges) +end diff --git a/pkg/images/imfit/src/t_imsurfit.x b/pkg/images/imfit/src/t_imsurfit.x new file mode 100644 index 00000000..2a93b8b2 --- /dev/null +++ b/pkg/images/imfit/src/t_imsurfit.x @@ -0,0 +1,400 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> +include "imsurfit.h" + +# T_IMSURFIT -- Fit a surface function to an image +# +# 1. A user selected function is fit to each surface. +# 2. Only the selected regions of the image are fit. +# 3. Deviant pixels may be rejected from the fit. +# 4. The user selects the type of output image. The choices are: +# a. the fitted image. +# b. the input image with deviant pixels replaced by +# the fitted values +# c. the input image minus the fitted image. +# d. the ratio of the input image and the fit where +# pixels less than div_min are set to a ratio of 1. + + +procedure t_imsurfit () + +char imtlist1[SZ_LINE] # Input image list +char imtlist2[SZ_LINE] # Output image list +char image1[SZ_FNAME] # Input image +char image2[SZ_FNAME] # Output image + +char str[SZ_LINE], region_str[SZ_LINE] +int list1, list2, region_type +pointer im1, im2, imfit, gl, sp + +bool clgetb() +int imtopen(), imtgetim(), imtlen(), btoi(), clgeti(), clgwrd() +pointer immap() +real clgetr() + +begin + # Allocate space for imfit structure. + call smark (sp) + call salloc (imfit, LEN_IMSFSTRUCT, TY_STRUCT) + + # Get task parameters. + call clgstr ("input", imtlist1, SZ_FNAME) + call clgstr ("output", imtlist2, SZ_FNAME) + TYPE_OUTPUT(imfit) = clgwrd ("type_output", str, SZ_LINE, + ",fit,clean,residual,response,") + DIV_MIN(imfit) = clgetr ("div_min") + + # Get surface ftting parameters. + SURFACE_TYPE(imfit) = clgwrd ("function", str, SZ_LINE, + ",legendre,chebyshev,spline3,spline1,") + XORDER(imfit) = clgeti ("xorder") + YORDER(imfit) = clgeti ("yorder") + CROSS_TERMS(imfit) = btoi (clgetb ("cross_terms")) + + # Get median processing parameters. + XMEDIAN(imfit) = clgeti ("xmedian") + YMEDIAN(imfit) = clgeti ("ymedian") + MEDIAN_PERCENT(imfit) = clgetr ("median_percent") + if (XMEDIAN(imfit) > 1 || YMEDIAN(imfit) > 1) + MEDIAN(imfit) = YES + else + MEDIAN(imfit) = NO + + # Get rejection cycle parameters. + NITER(imfit) = clgeti ("niter") + LOWER(imfit) = clgetr ("lower") + UPPER(imfit) = clgetr ("upper") + NGROW(imfit) = clgeti ("ngrow") + + if (MEDIAN(IMFIT) == YES) { + REJECT(imfit) = NO + NITER(imfit) = 0 + } else if (NITER(imfit) > 0 && (LOWER(imfit) > 0. || UPPER(imfit) > 0.)) + REJECT(imfit) = YES + else { + REJECT(imfit) = NO + NITER(imfit) = 0 + } + + # Checking sigmas for cleaning. + if (TYPE_OUTPUT(imfit) == CLEAN && MEDIAN(imfit) == YES) + call error (0, + "T_IMSURFIT: Clean option and median processing are exclusive.") + if (TYPE_OUTPUT(imfit) == CLEAN && NITER(imfit) <= 0) + call error (0, "T_IMSURFIT: Clean option requires non-zero niter.") + if (TYPE_OUTPUT(imfit) == CLEAN && LOWER(imfit) <= 0. && + UPPER(imfit) <= 0.) + call error (0, "T_IMSURFIT: Clean option requires non-zero sigma.") + + # Get regions to be fit. + gl = NULL + region_type = clgwrd ("regions", str, SZ_LINE, + ",all,columns,rows,border,sections,circle,invcircle,") + switch (region_type) { + case ALL: + ; + case BORDER: + call clgstr ("border", region_str, SZ_LINE) + case SECTIONS: + call clgstr ("sections", region_str, SZ_LINE) + case COLUMNS: + call clgstr ("columns", region_str, SZ_LINE) + case ROWS: + call clgstr ("rows", region_str, SZ_LINE) + case CIRCLE, INVCIRCLE: + call clgstr ("circle", region_str, SZ_LINE) + } + + # Expand the input and output image lists. + list1 = imtopen (imtlist1) + list2 = imtopen (imtlist2) + if (imtlen (list1) != imtlen (list2)) { + call imtclose (list1) + call imtclose (list2) + call error (0, "Number of input and output images not the same.") + } + + # Do each set of input and output images. + while ((imtgetim (list1, image1, SZ_FNAME) != EOF) && + (imtgetim (list2, image2, SZ_FNAME) != EOF)) { + + im1 = immap (image1, READ_ONLY, 0) + im2 = immap (image2, NEW_COPY, im1) + + iferr { + if (region_type != ALL) + call make_good_list (im1, gl, region_type, region_str) + call imsurfit (im1, im2, imfit, gl) + } then + call erract (EA_WARN) + + call imunmap (im1) + call imunmap (im2) + call prl_free (gl) + } + + # Cleanup. + call sfree (sp) + call imtclose (list1) + call imtclose (list2) +end + + +# MAKE_GOOD_LIST -- Procedure to make a list of good regions. The program +# returns an error message if no good regions are defined. The good +# list parameter is set to NULL if the whole image is to be fit. This routine +# uses both the ranges and pixlist package which will be replaced by image +# masking. + +procedure make_good_list (im, gl, region_type, region_string) + +pointer im # pointer to the image +pointer gl # good pixel list descriptor +int region_type # type of good region +char region_string[ARB] # region parameters + +int i, ip, zero, nvals, range_min, r2, xdist, max_nranges +int x1, x2, y1, y2, temp, border, xcenter, ycenter, radius +int columns[7] +pointer sp, ranges, list + +bool is_in_rangelist() +int is_next_number(), is_decode_ranges(), open(), fscan(), nscan(), ctoi() +errchk open, close + +begin + # Determine the maximum number of images. + max_nranges = IM_LEN(im,1) + + # Allocate working space. + call smark (sp) + call salloc (ranges, 3 * max_nranges + 1, TY_INT) + + # Compute the good pixel list. + switch (region_type) { + case ROWS: + + # Decode the row ranges. + if (is_decode_ranges (region_string, Memi[ranges], max_nranges, 1, + int (IM_LEN(im,2)), nvals) == ERR) + call error (0, "MAKE_GOOD_LIST: Error decoding row string.") + if (nvals == 0) + call error (0, "MAKE_GOOD_LIST: no good rows.") + if (nvals == IM_LEN(im,2)) { + call sfree (sp) + return + } + + # Intialize the good pixel list. + call prl_init (gl, int (IM_LEN(im,1)), int (IM_LEN(im,2))) + + # Set column limits using the ranges format. + columns[1] = 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + + # Set column limits for the specied lines. + zero = 0 + range_min = is_next_number (Memi[ranges], zero) + while (range_min != EOF) { + for (i = range_min; i <= IM_LEN(im,2) + 1; i = i + 1) { + if (!is_in_rangelist (Memi[ranges], i) || + i == IM_LEN(im,2)+1) { + call prl_put_ranges (gl, range_min, i-1, columns) + break + } + } + range_min = is_next_number (Memi[ranges], i) + } + + case COLUMNS: + + # Set the specified columns. + if (is_decode_ranges (region_string, Memi[ranges], max_nranges, 1, + int (IM_LEN(im,1)), nvals) == ERR) + call error (0, "MAKE_GOOD_LIST: Error decoding column string.") + if (nvals == 0) + call error (0, "MAKE_GOOD_LIST: No good columns.") + if (nvals == IM_LEN(im,1)) { + call sfree (sp) + return + } + + # Make the good pixel list. + call prl_init (gl, int (IM_LEN(im,1)), int (IM_LEN(im,2))) + call prl_add_ranges (gl, 1, int (IM_LEN(im,2)), Memi[ranges]) + + case CIRCLE, INVCIRCLE: + + # Get the parameters of the circle. + ip = 1 + if (ctoi (region_string, ip, xcenter) <= 0) + call error (0, "MAKE_GOOD_LIST: Error decoding xcenter.") + if (ctoi (region_string, ip, ycenter) <= 0) + call error (0, "MAKE_GOOD_LIST: Error decoding ycenter.") + if (ctoi (region_string, ip, radius) <= 0) + call error (0, "MAKE_GOOD_LIST: Error decoding radius.") + + y1 = max (1, ycenter - radius) + y2 = min (int (IM_LEN(im,2)), ycenter + radius) + x1 = max (1, xcenter - radius) + x2 = min (int (IM_LEN(im,1)), xcenter + radius) + if (region_type == CIRCLE) { + if (y1 > IM_LEN(im,2) || y2 < 1 || x1 > IM_LEN(im,1) || x2 < 1) + call error (0, "MAKE_GOOD_LIST: No good regions.") + } + + # Create the good pixel list. + call prl_init (gl, int (IM_LEN(im,1)), int (IM_LEN(im,2))) + + r2 = radius ** 2 + if (region_type == CIRCLE) { + do i = y1, y2 { + xdist = sqrt (real (r2 - (ycenter - i) ** 2)) + x1 = max (1, xcenter - xdist) + x2 = min (IM_LEN(im,1), xcenter + xdist) + columns[1] = x1 + columns[2] = x2 + columns[3] = 1 + columns[4] = NULL + call prl_put_ranges (gl, i, i, columns) + } + } else if (region_type == INVCIRCLE) { + do i = 1, y1 - 1 { + columns[1] = 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + call prl_put_ranges (gl, i, i, columns) + } + do i = y2 + 1, IM_LEN(im,2) { + columns[1] = 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + call prl_put_ranges (gl, i, i, columns) + } + do i = y1, y2 { + xdist = sqrt (real (r2 - (ycenter - i) ** 2)) + x1 = max (1, xcenter - xdist) + x2 = min (IM_LEN(im,1), xcenter + xdist) + if (x1 > 1) { + columns[1] = 1 + columns[2] = x1 - 1 + columns[3] = 1 + if (x2 < IM_LEN(im,1)) { + columns[4] = x2 + 1 + columns[5] = IM_LEN(im,1) + columns[6] = 1 + columns[7] = NULL + } else + columns[4] = NULL + } else if (x2 < IM_LEN(im,1)) { + columns[1] = x2 + 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + } else + columns[1] = NULL + call prl_put_ranges (gl, i, i, columns) + } + } + + + case SECTIONS: + + # Open file of sections. + list = open (region_string, READ_ONLY, TEXT_FILE) + call prl_init (gl, int (IM_LEN(im,1)), int (IM_LEN(im,2))) + + # Scan the list. + while (fscan (list) != EOF) { + + # Fetch parameters from list. + call gargi (x1) + call gargi (x2) + call gargi (y1) + call gargi (y2) + if (nscan() != 4) + next + + # Check and correct for out of bounds limits. + x1 = max (1, min (IM_LEN(im,1), x1)) + x2 = min (IM_LEN(im,1), max (1, x2)) + y1 = max (1, min (IM_LEN(im,2), y1)) + y2 = min (IM_LEN(im,2), max (1, y2)) + + # Check the order. + if (x2 < x1) { + temp = x1 + x1 = x2 + x2 = temp + } + if (y2 < y1) { + temp = y1 + y1 = y2 + y2 = temp + } + + # If entire image return. + if ((x1 == 1) && (x2 == IM_LEN(im,1)) && (y1 == 1) && + (y2 == IM_LEN(im,2))) { + call prl_free (gl) + gl = NULL + break + } + + # Set ranges. + columns[1] = x1 + columns[2] = x2 + columns[3] = 1 + columns[4] = NULL + call prl_add_ranges (gl, y1, y2, columns) + } + + call close (list) + + case BORDER: + + # Decode border parameter. + ip = 1 + if (ctoi (region_string, ip, border) == ERR) + call error (0, "MAKE_GOOD_LIST: Error decoding border string.") + if (border < 1) + call error (0, "MAKE_GOOD_LIST: No border.") + if ((border > IM_LEN(im,1)/2) && (border > IM_LEN(im,2)/2)) { + call sfree (sp) + return + } + + # Intialize list. + call prl_init (gl, int (IM_LEN(im,1)), int (IM_LEN(im,2))) + y1 = 1 + border - 1 + y2 = IM_LEN(im,2) - border + 1 + columns[1] = 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + + # Set ranges for top and bottom edges of image. + call prl_put_ranges (gl, 1, y1, columns) + call prl_put_ranges (gl, y2, int (IM_LEN(im,2)), columns) + + columns[1] = 1 + columns[2] = y1 + columns[3] = 1 + columns[4] = NULL + call prl_put_ranges (gl, y1 + 1, y2 - 1, columns) + + columns[1] = IM_LEN(im,1) - border + 1 + columns[2] = IM_LEN(im,1) + columns[3] = 1 + columns[4] = NULL + call prl_add_ranges (gl, y1 + 1, y2 - 1, columns) + } + + call sfree (sp) +end diff --git a/pkg/images/imfit/src/t_lineclean.x b/pkg/images/imfit/src/t_lineclean.x new file mode 100644 index 00000000..4acb9752 --- /dev/null +++ b/pkg/images/imfit/src/t_lineclean.x @@ -0,0 +1,270 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <pkg/gtools.h> + +# LINECLEAN -- Fit a function to the image lines and output an image +# with rejected points replaced by the fit. The fitting parameters may be +# set interactively using the icfit package. + +procedure t_lineclean () + +int listin # Input image list +int listout # Output image list +char sample[SZ_LINE] # Sample ranges +int naverage # Sample averaging size +char function[SZ_LINE] # Curve fitting function +int order # Order of curve fitting function +real low_reject, high_reject # Rejection threshold +int niterate # Number of rejection iterations +real grow # Rejection growing radius +bool interactive # Interactive? + +char input[SZ_LINE] # Input image +char output[SZ_FNAME] # Output image +pointer in, out # IMIO pointers +pointer ic # ICFIT pointer +pointer gt # GTOOLS pointer + +int imtopen(), imtgetim(), imtlen(), gt_init() +int clgeti() +real clgetr() +bool clgetb() + +begin + # Get input and output lists and check that the number of images + # are the same. + + call clgstr ("input", input, SZ_LINE) + listin = imtopen (input) + call clgstr ("output", input, SZ_LINE) + listout = imtopen (input) + if (imtlen (listin) != imtlen (listout)) { + call imtclose (listin) + call imtclose (listout) + call error (0, "Input and output image lists do not match") + } + + # Get task parameters. + + call clgstr ("sample", sample, SZ_LINE) + naverage = clgeti ("naverage") + call clgstr ("function", function, SZ_LINE) + order = clgeti ("order") + low_reject = clgetr ("low_reject") + high_reject = clgetr ("high_reject") + niterate = clgeti ("niterate") + grow = clgetr ("grow") + interactive = clgetb ("interactive") + + + # Set the ICFIT pointer structure. + call ic_open (ic) + call ic_pstr (ic, "sample", sample) + call ic_puti (ic, "naverage", naverage) + call ic_pstr (ic, "function", function) + call ic_puti (ic, "order", order) + call ic_putr (ic, "low", low_reject) + call ic_putr (ic, "high", high_reject) + call ic_puti (ic, "niterate", niterate) + call ic_putr (ic, "grow", grow) + call ic_pstr (ic, "ylabel", "") + + gt = gt_init() + call gt_sets (gt, GTTYPE, "line") + + # Clean the lines in each input image. + + while ((imtgetim (listin, input, SZ_FNAME) != EOF) && + (imtgetim (listout, output, SZ_FNAME) != EOF)) { + + call lc_immap (input, output, in, out) + call lineclean (in, out, ic, gt, input, interactive) + call imunmap (in) + call imunmap (out) + } + + call ic_closer (ic) + call gt_free (gt) + call imtclose (listin) + call imtclose (listout) +end + + +# LINECLEAN -- Given the image descriptor determine the fitting function +# for each line and create an output image. If the interactive flag +# is set then set the fitting parameters interactively. + +procedure lineclean (in, out, ic, gt, title, interactive) + +pointer in # IMIO pointer for input image +pointer out # IMIO pointer for output image +pointer ic # ICFIT pointer +pointer gt # GTIO pointer +char title[ARB] # Title +bool interactive # Interactive? + +char graphics[SZ_FNAME] +int i, nx, new +long inline[IM_MAXDIM], outline[IM_MAXDIM] +pointer cv, gp, sp, x, wts, indata, outdata + +int lf_getline(), imgnlr(), impnlr(), strlen() +pointer gopen() + +begin + # Allocate memory for curve fitting. + + nx = IM_LEN(in, 1) + + call smark (sp) + call salloc (x, nx, TY_REAL) + call salloc (wts, nx, TY_REAL) + + do i = 1, nx + Memr[x+i-1] = i + call amovkr (1., Memr[wts], nx) + + call ic_putr (ic, "xmin", Memr[x]) + call ic_putr (ic, "xmax", Memr[x+nx-1]) + + # If the interactive flag is set then use icg_fit to set the + # fitting parameters. Get_fitline returns EOF when the user + # is done. The weights are reset since the user may delete + # points. + + if (interactive) { + call clgstr ("graphics", graphics, SZ_FNAME) + gp = gopen ("stdgraph", NEW_FILE, STDGRAPH) + + i = strlen (title) + while (lf_getline (ic, gt, in, indata, inline, title)!=EOF) { + title[i + 1] = EOS + call icg_fit (ic, gp, "cursor", gt, cv, Memr[x], Memr[indata], + Memr[wts], nx) + call amovkr (1., Memr[wts], nx) + } + call gclose (gp) + } + + # Loop through each input image line and create an output image line. + + new = YES + call amovkl (long(1), inline, IM_MAXDIM) + call amovkl (long(1), outline, IM_MAXDIM) + + while (imgnlr (in, indata, inline) != EOF) { + if (impnlr (out, outdata, outline) == EOF) + call error (0, "Error writing output image") + + call ic_fit (ic, cv, Memr[x], Memr[indata], Memr[wts], + nx, new, YES, new, new) + new = NO + + call ic_clean (ic, cv, Memr[x], Memr[indata], Memr[wts], nx) + + call amovr (Memr[indata], Memr[outdata], nx) + } + + call cvfree (cv) + call sfree (sp) +end + + +# LC_IMMAP -- Map images for lineclean. + +procedure lc_immap (input, output, in, out) + +char input[ARB] # Input image +char output[ARB] # Output image +pointer in # Input IMIO pointer +pointer out # Output IMIO pointer + +pointer sp, root, sect +int imaccess() +pointer immap() + +begin + # Get the root name and section of the input image. + + call smark (sp) + call salloc (root, SZ_FNAME, TY_CHAR) + call salloc (sect, SZ_FNAME, TY_CHAR) + + call get_root (input, Memc[root], SZ_FNAME) + call get_section (input, Memc[sect], SZ_FNAME) + + # If the output image is not accessible then create it as a new copy + # of the full input image. + + if (imaccess (output, 0) == NO) + call img_imcopy (Memc[root], output, false) + + # Map the input and output images. + + in = immap (input, READ_ONLY, 0) + + call sprintf (Memc[root], SZ_FNAME, "%s%s") + call pargstr (output) + call pargstr (Memc[sect]) + out = immap (Memc[root], READ_WRITE, 0) + + call sfree (sp) +end + + +# LF_GETLINE -- Get an image line to be fit interactively. Return EOF +# when the user enters EOF or CR. Default line is the first line and +# the out of bounds lines are silently limited to the nearest in bounds line. + +int procedure lf_getline (ic, gt, im, data, v, title) + +pointer ic # ICFIT pointer +pointer gt # GTOOLS pointer +pointer im # IMIO pointer +pointer data # Image data +long v[ARB] # Image line vector +char title[ARB] # Title + +int i +char line[SZ_LINE] +int getline(), nscan(), imgnlr() + +begin + call sprintf (title, SZ_LINE, "%s: Fit line =") + call pargstr (title) + + call printf ("%s ") + call pargstr (title) + call flush (STDOUT) + + if (getline(STDIN, line) == EOF) + return (EOF) + call sscan (line) + + call amovkl (long (1), v, IM_MAXDIM) + do i = 2, max (2, IM_NDIM(im)) { + call gargl (v[i]) + if (nscan() == 0) + return (EOF) + else if (nscan() != i - 1) + break + + if (IM_NDIM(im) == 1) + v[i] = 1 + else + v[i] = max (1, min (IM_LEN(im, i), v[i])) + + call sprintf (title, SZ_LINE, "%s %d") + call pargstr (title) + call pargl (v[i]) + } + + call sprintf (title, SZ_LINE, "%s\n%s") + call pargstr (title) + call pargstr (IM_TITLE(im)) + call ic_pstr (ic, "xlabel", "Column") + call gt_sets (gt, GTTITLE, title) + + return (imgnlr (im, data, v)) +end |