# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. include include include include "rfits.h" # RFT_READ_IMAGE -- Convert FITS image pixels to IRAF image pixels. procedure rft_read_image (fits_fd, fits, im) int fits_fd # FITS file descriptor pointer fits # FITS data structure pointer im # IRAF image descriptor int i, npix, npix_record, blksize, ndummy long v[IM_MAXDIM], nlines, il pointer tempbuf, buf real linemax, linemin, lirafmin, lirafmax double dblank long clktime() int fstati(), rft_init_read_pixels(), rft_read_pixels() errchk malloc, mfree, rft_init_read_pixels, rft_read_pixels, rft_lscale_pix errchk rft_lchange_pix, rft_rchange_pix, rfit_dchange_pix, rft_put_image_line errchk rft_pix_limits, rft_rscale_pix, rft_dscale_pix include "rfits.com" begin # No pixel file was created. if (NAXIS(im) == 0) { if (short_header == YES || long_header == YES) { if (long_header == NO) call printf (" ") call printf ("Warning: No pixel file created\n") } return } # Compute the number of columns and lines in the image. npix = NAXISN(im, 1) nlines = 1 do i = 2, NAXIS(im) nlines = nlines * NAXISN(im, i) lirafmax = -MAX_REAL lirafmin = MAX_REAL # Compute the number of pixels per record and the number of records # per output block. npix_record = len_record * FITS_BYTE / abs (BITPIX(fits)) blksize = fstati (fits_fd, F_SZBBLK) if (mod (blksize, FITS_RECORD) == 0) blksize = blksize / FITS_RECORD else blksize = 1 # FITS data is converted to type LONG, REAL or DOUBLE. If BITPIX is # not one of the MII types then rft_read_pixels returns an ERROR. call amovkl (long(1), v, IM_MAXDIM) switch (BITPIX(fits)) { case FITS_REAL: # Allocate temporary space. call malloc (tempbuf, npix, TY_REAL) # Initialize the read. i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, TY_REAL) # Turn on the ieee NaN mapping. call ieesnanr (blank) call ieemapr (YES, NO) #call ieezstatr () NBPIX(im) = 0 # Allocate the space for the output line, read in the image # line, convert from the ieee to native format, and compute the # minimum and maximum. do il = 1, nlines { call rft_put_image_line (im, buf, v, PIXTYPE(im)) if (rft_read_pixels (fits_fd, Memr[tempbuf], npix, NRECORDS(fits), blksize) != npix) call printf ("Error reading FITS data\n") if (SCALE(fits) == YES) call rft_rscale_pix (Memr[tempbuf], buf, npix, FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) else call rft_rchange_pix (Memr[tempbuf], buf, npix, PIXTYPE(im)) call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) lirafmax = max (lirafmax, linemax) lirafmin = min (lirafmin, linemin) } # Set the number of bad pixels. call ieestatr (NBPIX(im), ndummy) # Free space. call mfree (tempbuf, TY_REAL) case FITS_DOUBLE: # Allocate temporary space. call malloc (tempbuf, npix, TY_DOUBLE) # Initialize the read. i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, TY_DOUBLE) # Turn on the ieee NaN mapping. dblank = blank call ieesnand (dblank) call ieemapd (YES, NO) #call ieezstatd () NBPIX(im) = 0 # Allocate the space for the output line, read in the image # line, convert from the ieee to native format, and compute the # minimum and maximum. do il = 1, nlines { call rft_put_image_line (im, buf, v, PIXTYPE(im)) if (rft_read_pixels (fits_fd, Memd[tempbuf], npix, NRECORDS(fits), blksize) != npix) call printf ("Error reading FITS data\n") if (SCALE(fits) == YES) call rft_dscale_pix (Memd[tempbuf], buf, npix, FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) else call rft_dchange_pix (Memd[tempbuf], buf, npix, PIXTYPE(im)) call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) if (IS_INDEFR(linemax)) lirafmax = INDEFR else lirafmax = max (lirafmax, linemax) if (IS_INDEFR(linemin)) lirafmin = INDEFR else lirafmin = min (lirafmin, linemin) } # Set the number of bad pixels. call ieestatd (NBPIX(im), ndummy) # Free space. call mfree (tempbuf, TY_DOUBLE) default: # Allocate the required space. call malloc (tempbuf, npix, TY_LONG) # Allocate the space for the output line, read in the image # line, convert from the ieee to native format, and compute the # minimum and maximum. i = rft_init_read_pixels (npix_record, BITPIX(fits), LSBF, TY_LONG) do il = 1, nlines { call rft_put_image_line (im, buf, v, PIXTYPE(im)) if (rft_read_pixels (fits_fd, Meml[tempbuf], npix, NRECORDS(fits), blksize) != npix) call printf ("Error reading FITS data\n") if (SCALE(fits) == YES) call rft_lscale_pix (Meml[tempbuf], buf, npix, FITS_BSCALE(fits), FITS_BZERO(fits), PIXTYPE(im)) else call rft_lchange_pix (Meml[tempbuf], buf, npix, PIXTYPE(im)) if (BLANKS(fits) == YES) call rft_map_blanks (Meml[tempbuf], buf, npix, PIXTYPE(im), BLANK_VALUE(fits), blank, NBPIX(im)) call rft_pix_limits (buf, npix, PIXTYPE(im), linemin, linemax) lirafmax = max (lirafmax, linemax) lirafmin = min (lirafmin, linemin) } # Free space. call mfree (tempbuf, TY_LONG) } IRAFMIN(im) = lirafmin IRAFMAX(im) = lirafmax LIMTIME(im) = clktime (long(0)) if (short_header == YES || long_header == YES) { if (NBPIX (im) != 0) { if (long_header == NO) call printf (" ") call printf ("Warning: %d bad pixels replaced in image\n") call pargl (NBPIX (im)) } if (IS_INDEFR(lirafmax) || lirafmax > MAX_REAL) { if (long_header == NO) call printf (" ") call printf ("Warning: image contains pixel values > %g\n") call pargr (MAX_REAL) } if (IS_INDEFR(lirafmin) || lirafmin < -MAX_REAL) { if (long_header == NO) call printf (" ") call printf ("Warning: image contains pixel values < %g\n") call pargr (-MAX_REAL) } } end # RFT_PUT_IMAGE_LINE -- Procedure to output an image line to and IRAF file. procedure rft_put_image_line (im, buf, v, data_type) pointer im # IRAF image descriptor pointer buf # Pointer to output image line long v[ARB] # imio pointer int data_type # output pixel type int impnll(), impnlr(), impnld(), impnlx() errchk impnll, impnlr, impnld, impnlx begin switch (data_type) { case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: if (impnll (im, buf, v) == EOF) call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") case TY_REAL: if (impnlr (im, buf, v) == EOF) call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") case TY_DOUBLE: if (impnld (im, buf, v) == EOF) call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") case TY_COMPLEX: if (impnlx (im, buf, v) == EOF) call error (3, "RFT_PUT_IMAGE_LINE: Error writing FITS data") default: call error (10, "RFT_PUT_IMAGE_LINE: Unsupported IRAF image type") } end # RFT_RSCALE_PIX -- Procedure to convert an IRAF image line from type real # to the requested output data type with optional scaling using the # FITS parameters BSCALE and BZERO. procedure rft_rscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) real inbuf[ARB] # buffer of FITS integers pointer outbuf # pointer to output image line int npix # number of pixels double bscale, bzero # FITS bscale and bzero int data_type # IRAF image pixel type errchk altmdr, achtrl, amovr, achtrd, achtrx begin switch (data_type) { case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: call altmdr (inbuf, inbuf, npix, bscale, bzero) call achtrl (inbuf, Meml[outbuf], npix) case TY_REAL: call altmdr (inbuf, inbuf, npix, bscale, bzero) call amovr (inbuf, Memr[outbuf], npix) case TY_DOUBLE: call altmdr (inbuf, inbuf, npix, bscale, bzero) call achtrd (inbuf, Memd[outbuf], npix) case TY_COMPLEX: call altmdr (inbuf, inbuf, npix, bscale, bzero) call achtrx (inbuf, Memx[outbuf], npix) default: call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") } end # RFT_DSCALE_PIX -- Procedure to convert an IRAF image line from type double # to the requested output data type with optional scaling using the # FITS parameters BSCALE and BZERO. procedure rft_dscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) double inbuf[ARB] # buffer of FITS integers pointer outbuf # pointer to output image line int npix # number of pixels double bscale, bzero # FITS bscale and bzero int data_type # IRAF image pixel type errchk altmd, achtdl, amovd, achtdr, achtdx begin switch (data_type) { case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: call altmd (inbuf, inbuf, npix, bscale, bzero) call achtdl (inbuf, Meml[outbuf], npix) case TY_REAL: call altmd (inbuf, inbuf, npix, bscale, bzero) call achtdr (inbuf, Memr[outbuf], npix) case TY_DOUBLE: call altmd (inbuf, inbuf, npix, bscale, bzero) call amovd (inbuf, Memd[outbuf], npix) case TY_COMPLEX: call altmd (inbuf, inbuf, npix, bscale, bzero) call achtdx (inbuf, Memx[outbuf], npix) default: call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") } end # RFT_LSCALE_PIX -- Procedure to convert an IRAF image line from type long # to the requested output data type with optional scaling using the # FITS parameters BSCALE and BZERO. procedure rft_lscale_pix (inbuf, outbuf, npix, bscale, bzero, data_type) long inbuf[ARB] # buffer of FITS integers pointer outbuf # pointer to output image line int npix # number of pixels double bscale, bzero # FITS bscale and bzero int data_type # IRAF image pixel type errchk achtll, achtlr, achtld, achtlx errchk altml, altmr, altmd, altmx begin switch (data_type) { case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: call achtll (inbuf, Meml[outbuf], npix) call altml (Meml[outbuf], Meml[outbuf], npix, bscale, bzero) case TY_REAL: call altmlr (inbuf, Memr[outbuf], npix, bscale, bzero) case TY_DOUBLE: call achtld (inbuf, Memd[outbuf], npix) call altmd (Memd[outbuf], Memd[outbuf], npix, bscale, bzero) case TY_COMPLEX: call achtlx (inbuf, Memx[outbuf], npix) call altmx (Memx[outbuf], Memx[outbuf], npix, real (bscale), real (bzero)) default: call error (10, "RFT_SCALE_LINE: Illegal IRAF image type") } end # RFT_RCHANGE_PIX -- Procedure to change a line of real numbers to the # IRAF image type. procedure rft_rchange_pix (inbuf, outbuf, npix, data_type) real inbuf[ARB] # array of FITS integers pointer outbuf # pointer to IRAF image line int npix # number of pixels int data_type # IRAF pixel type errchk achtrl, amovr, achtrd, achtrx begin switch (data_type) { case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: call achtrl (inbuf, Meml[outbuf], npix) case TY_REAL: call amovr (inbuf, Memr[outbuf], npix) case TY_DOUBLE: call achtrd (inbuf, Memd[outbuf], npix) case TY_COMPLEX: call achtrx (inbuf, Memx[outbuf], npix) default: call error (10, "RFT_RCHANGE_LINE: Illegal IRAF image type") } end # RFT_DCHANGE_PIX -- Procedure to change a line of double precision numbers # to the IRAF image type. procedure rft_dchange_pix (inbuf, outbuf, npix, data_type) double inbuf[ARB] # array of FITS integers pointer outbuf # pointer to IRAF image line int npix # number of pixels int data_type # IRAF pixel type errchk achtdl, achtdr, amovd, achtdx begin switch (data_type) { case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: call achtdl (inbuf, Meml[outbuf], npix) case TY_REAL: call achtdr (inbuf, Memr[outbuf], npix) case TY_DOUBLE: call amovd (inbuf, Memd[outbuf], npix) case TY_COMPLEX: call achtdx (inbuf, Memx[outbuf], npix) default: call error (10, "RFT_DCHANGE_LINE: Illegal IRAF image type") } end # RFT_LCHANGE_PIX -- Procedure to change a line of long integers to the # IRAF image type. procedure rft_lchange_pix (inbuf, outbuf, npix, data_type) long inbuf[ARB] # array of FITS integers pointer outbuf # pointer to IRAF image line int npix # number of pixels int data_type # IRAF pixel type begin switch (data_type) { case TY_SHORT, TY_USHORT, TY_INT, TY_LONG: call achtll (inbuf, Meml[outbuf], npix) case TY_REAL: call achtlr (inbuf, Memr[outbuf], npix) case TY_DOUBLE: call achtld (inbuf, Memd[outbuf], npix) case TY_COMPLEX: call achtlx (inbuf, Memx[outbuf], npix) default: call error (10, "RFT_CHANGE_LINE: Illegal IRAF image type") } end # RFT_MAP_BLANKS -- Map the blank pixels. Currently only the number of blank # pixels is determined without an further mapping. procedure rft_map_blanks (a, buf, npts, pixtype, blank_value, blank, nbadpix) long a[ARB] # integer input buffer pointer buf # pointer to output image buffer int npts # number of points int pixtype # image data type long blank_value # FITS blank value real blank # user blank value long nbadpix # number of bad pixels int i begin # Do blank mapping here switch (pixtype) { case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: do i = 1, npts { if (a[i] == blank_value) { nbadpix = nbadpix + 1 Meml[buf+i-1] = blank } } case TY_REAL: do i = 1, npts { if (a[i] == blank_value) { nbadpix = nbadpix + 1 Memr[buf+i-1] = blank } } case TY_DOUBLE: do i = 1, npts { if (a[i] == blank_value) { nbadpix = nbadpix + 1 Memd[buf+i-1] = blank } } case TY_COMPLEX: do i = 1, npts { if (a[i] == blank_value) { nbadpix = nbadpix + 1 Memx[buf+i-1] = blank } } } end # RFT_PIX_LIMITS -- Procedure to determine to maxmimum and minimum values in a # line. Note that double precision is somewhat of a special case because # MAX_DOUBLE is a lot less than the maximum permitted ieee numbers for iraf. procedure rft_pix_limits (buf, npix, pixtype, linemin, linemax) pointer buf # pointer to IRAF image line int npix # number of pixels int pixtype # output data type real linemax, linemin # min and max pixel values long lmax, lmin real rmax, rmin double dmax, dmin complex xmax, xmin begin switch (pixtype) { case TY_SHORT, TY_INT, TY_USHORT, TY_LONG: call aliml (Meml[buf], npix, lmin, lmax) linemax = lmax linemin = lmin case TY_REAL: call alimr (Memr[buf], npix, rmin, rmax) linemax = rmax linemin = rmin case TY_DOUBLE: call alimd (Memd[buf], npix, dmin, dmax) if (dmax > MAX_REAL) linemax = INDEFR else linemax = dmax if (dmin < -MAX_REAL) linemin = INDEFR else linemin = dmin case TY_COMPLEX: call alimx (Memx[buf], npix, xmin, xmax) linemax = xmax linemin = xmin default: call error (30, "RFT_PIX_LIMITS: Unknown IRAF type") } end # ALTMDR -- procedure to scale a long vector into a real vector using # double precision constants to preserve accuracy procedure altmlr (a, b, npix, bscale, bzero) long a[ARB] # input array real b[ARB] # output array int npix # number of pixels double bscale, bzero # scaling parameters int i begin do i = 1, npix b[i] = a[i] * bscale + bzero end # ALTMDR -- procedure to scale a real vector with double precision constants. procedure altmdr (a, b, npix, bscale, bzero) real a[ARB] # input array real b[ARB] # output array int npix # number of pixels double bscale, bzero # scaling parameters int i begin do i = 1, npix b[i] = a[i] * bscale + bzero end