diff options
Diffstat (limited to 'noao/mtlocal/pds')
-rw-r--r-- | noao/mtlocal/pds/README | 1 | ||||
-rw-r--r-- | noao/mtlocal/pds/mkpkg | 14 | ||||
-rw-r--r-- | noao/mtlocal/pds/pds_read.x | 71 | ||||
-rw-r--r-- | noao/mtlocal/pds/pds_rheader.x | 234 | ||||
-rw-r--r-- | noao/mtlocal/pds/pds_rimage.x | 74 | ||||
-rw-r--r-- | noao/mtlocal/pds/pds_rpixels.x | 182 | ||||
-rw-r--r-- | noao/mtlocal/pds/rpds.com | 13 | ||||
-rw-r--r-- | noao/mtlocal/pds/rpds.doc | 83 | ||||
-rw-r--r-- | noao/mtlocal/pds/rpds.h | 88 | ||||
-rw-r--r-- | noao/mtlocal/pds/structure.doc | 105 | ||||
-rw-r--r-- | noao/mtlocal/pds/structure.hlp | 85 | ||||
-rw-r--r-- | noao/mtlocal/pds/t_pdsread.x | 127 |
12 files changed, 1077 insertions, 0 deletions
diff --git a/noao/mtlocal/pds/README b/noao/mtlocal/pds/README new file mode 100644 index 00000000..f10ad9c4 --- /dev/null +++ b/noao/mtlocal/pds/README @@ -0,0 +1 @@ +The code for the PDS reader. diff --git a/noao/mtlocal/pds/mkpkg b/noao/mtlocal/pds/mkpkg new file mode 100644 index 00000000..d24534ad --- /dev/null +++ b/noao/mtlocal/pds/mkpkg @@ -0,0 +1,14 @@ +# Pdsread library + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + t_pdsread.x rpds.com <fset.h> <error.h> + pds_read.x rpds.com rpds.h <imhdr.h> <error.h> + pds_rimage.x rpds.com rpds.h <imhdr.h> <mach.h> + pds_rheader.x rpds.com rpds.h <imhdr.h> <mii.h> <mach.h> + pds_rpixels.x rpds.com rpds.h <mii.h> <mach.h> + ; diff --git a/noao/mtlocal/pds/pds_read.x b/noao/mtlocal/pds/pds_read.x new file mode 100644 index 00000000..0cba96d7 --- /dev/null +++ b/noao/mtlocal/pds/pds_read.x @@ -0,0 +1,71 @@ + +include <error.h> +include <imhdr.h> +include "rpds.h" + +# PDS_READ -- Convert a PDS file +# An EOT is signalled by returning EOF. + +int procedure pds_read (pdsfile, iraffile) + +char pdsfile[ARB], iraffile[ARB] +int pds_fd +int stat +long parameters[LEN_PAR_ARRAY] +pointer im + +int pds_read_header(), mtopen() +pointer immap() + +errchk salloc, pds_read_header, pds_read_image, mtopen, immap, imdelete + +include "rpds.com" + +begin + # Open input PDS data + pds_fd = mtopen (pdsfile, READ_ONLY, 0) + + if (long_header == YES || short_header == YES) { + if (make_image == YES) { + call printf ("File: %s ") + call pargstr (iraffile) + } else { + call printf ("File: %s ") + call pargstr (pdsfile) + } + if (long_header == YES) + call printf ("\n") + } + + # Create IRAF image header. If only a header listing is desired + # then a temporary image header is created and later deleted. + + if (make_image == NO) + call strcpy ("dev$null", iraffile, SZ_FNAME) + + im = immap (iraffile, NEW_IMAGE, 0) + + # Read header. EOT is signalled by an EOF status from pds_read_header. + iferr { + stat = pds_read_header (pds_fd, im, parameters) + if (stat == EOF) + call printf ("End of data\n") + else { + # Create an IRAF image if desired + if (make_image == YES) + call pds_read_image (pds_fd, im, parameters) + } + } then + call erract (EA_WARN) + + if (long_header == YES) + call printf ("\n") + + # Close files and clean up + call imunmap (im) + if (stat == EOF || make_image == NO) + call imdelete (iraffile) + call close (pds_fd) + + return (stat) +end diff --git a/noao/mtlocal/pds/pds_rheader.x b/noao/mtlocal/pds/pds_rheader.x new file mode 100644 index 00000000..5032d987 --- /dev/null +++ b/noao/mtlocal/pds/pds_rheader.x @@ -0,0 +1,234 @@ +include <imhdr.h> +include <mii.h> +include <mach.h> +include "rpds.h" + +# PDS_READ_HEADER -- Read a PDS header. EOT is detected by an EOF on the +# first read and EOF is returned to the calling routine. Errors are +# passed to the calling routine. + +int procedure pds_read_header (pds_fd, im, parameters) + +int pds_fd +pointer im +long parameters[LEN_PAR_ARRAY] + +int nchars, sz_header, header[LEN_PDS_HEADER] +short temptext[LEN_PDS_TEXT] +char text[LEN_PDS_TEXT] + +int read(), pds_roundup() +short pds_unpacks() +long pds_unpackl() + +errchk read, miiupk + +include "rpds.com" + +begin + # Read the header record + sz_header = pds_roundup (LEN_PDS_HEADER, SZB_CHAR) / SZB_CHAR + nchars = read (pds_fd, header, sz_header) + if (nchars == EOF) + return (EOF) + else if (nchars != sz_header) + call error (1, "Error reading pds header.") + + # Unpack ID string, convert to ASCII and copy to image header + call miiupk (header, temptext, LEN_PDS_TEXT, MII_SHORT, TY_SHORT) + call pds_apdp8s (temptext, temptext, LEN_PDS_TEXT) + call pds_apdp059 (temptext, text, LEN_PDS_TEXT) + text[LEN_PDS_TEXT + 1] = EOS + call strcpy (text, TITLE(im), SZ_TITLE) + + # Unpack the remainder of the header + # If XCOORD or YCOORD are greater than TWO_TO_23 convert to + # -ve number using TWO_TO_24 + + P_DX(parameters) = DX(header) + P_DY(parameters) = DY(header) + P_NPTS_PER_SCAN(parameters) = NPTS_PER_SCAN(header) + P_NSCANS(parameters) = NSCANS(header) + P_SCANTYPE(parameters) = SCANTYPE(header) + P_SCANSPEED(parameters) = SCANSPEED(header) + P_SCANORIGIN(parameters) = SCANORIGIN(header) + P_CORNER(parameters) = CORNER(header) + P_NRECS_PER_SCAN(parameters) = NRECS_PER_SCAN(header) + P_XTRAVEL(parameters) = XTRAVEL(header) + P_YTRAVEL(parameters) = YTRAVEL(header) + P_NPTS_PER_REC(parameters) = NPTS_PER_REC(header) + P_XCOORD(parameters) = XCOORD(header) + if (P_XCOORD(parameters) >= TWO_TO_23) + P_XCOORD(parameters) = P_XCOORD(parameters) - TWO_TO_24 + P_YCOORD(parameters) = YCOORD(header) + if (P_YCOORD(parameters) >= TWO_TO_23) + P_YCOORD(parameters) = P_YCOORD(parameters) - TWO_TO_24 + + # Write parameters to header + CT_VALID(im) = NO + NAXIS(im) = 2 + NCOLS(im) = P_NPTS_PER_SCAN(parameters) + NLINES(im) = P_NSCANS(parameters) + + # print the header + call pds_print_header (text, parameters) + + return (OK) +end + +# PDS_UNPACKS -- Procedure to unpack a short header value. +# The header value is stored in the integer array buffer, beginning +# at byte number offset. The value is unpacked into a temporary +# buffer, temp and converted to SPP format using the mii routines. +# Finally the PDS 10 or 12 bit bytes are converted to an SPP short value. + +short procedure pds_unpacks (buffer, offset) + +int buffer[ARB], offset + +short value[1] +long temp[1] +errchk miiupk, miiupk + +begin + call bytmov (buffer, offset, temp, 1, SZB_MIISHORT) + call miiupk (temp, value[1], 1, MII_SHORT, TY_SHORT) + call pds_apdp8s (value[1], value[1], 1) + return (value[1]) +end + +# PDS_UNPACKL -- Procedure to unpack a 24 bit long header value. + +long procedure pds_unpackl (buffer, offset) + +int buffer[ARB], offset + +short temps[2] +long temp[1], value[1] +errchk miiupk, bytmov + +begin + call bytmov (buffer, offset, temp, 1, SZB_MIILONG) + call miiupk (temp, temps, 2, MII_SHORT, TY_SHORT) + call pds_apdp8s (temps, temps, 2) + value[1] = temps[1] * 10000b + temps[2] + return (value[1]) +end + +# PDS_APDP8S -- Precedure to change a 12 or 10 bit PDP8 value to a short integer +# value. + +procedure pds_apdp8s (a, b, npix) + +short a[npix], b[npix] +int npix + +int i + +begin + for (i=1; i <= npix; i = i + 1) + b[i] = (a[i] / 400b) * 100b + mod (int (a[i]), 400b) +end + +# PDS_APDP059 -- Procedure to convert PDP 059 code into ASCII + +procedure pds_apdp059 (a, b, nchar) + +char b[nchar] +int nchar +short a[nchar] + +int i, j +char table[LEN_TABLE] + +# Conversion table from PDS 059 code to ASCII +data table/ ' ', ' ', ' ', ' ', '$', ' ', ' ', '"', '(', ')', + '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', ' ', ' ', ' ', '=', + ' ', ' ', ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', + 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', + ' ', ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', ' ', ' ', ' ', ' ', ' ', EOS/ + +begin + for (i = 1; i <= nchar; i = i + 1) + b[i] = a[i] - 159 + + for (i = 1; i <= nchar; i = i + 1) { + j = b[i] + if (j < 1 || j > LEN_TABLE) + j = 1 + b[i] = table[j] + } +end + + + +# PDS_PRINT_HEADER -- Procedure to print the header. + +procedure pds_print_header (text, parameters) + +char text[LEN_PDS_TEXT] +long parameters[LEN_PAR_ARRAY] + +include "rpds.com" + +begin + if (long_header == YES) + call pds_long_header (text, parameters) + if (short_header == YES && long_header == NO) { + call printf ("ID: %.30s ") + call pargstr (text) + call printf ("size =%d * %d \n") + call pargl (P_NPTS_PER_SCAN(parameters)) + call pargl (P_NSCANS(parameters)) + } +end + +# PDS_LONG_HEADER -- Print a long header + +procedure pds_long_header (text, parameters) + +char text[LEN_PDS_TEXT] +long parameters[LEN_PAR_ARRAY] + +begin + call printf ("ID:%s\n") + call pargstr (text) + call printf ("NPTS = %d ") + call pargl (P_NPTS_PER_SCAN(parameters)) + call printf ("NSCANS = %d ") + call pargl (P_NSCANS(parameters)) + call printf ("NRECS/SCAN = %d ") + call pargl (P_NRECS_PER_SCAN(parameters)) + call printf ("PPERR = %d\n") + call pargl (P_NPTS_PER_REC(parameters)) + call printf ("SCANTYPE = %s ") + if (P_SCANTYPE(parameters) == RASTER) + call pargstr ("RASTER") + else if (P_SCANTYPE(parameters) == EDGE) + call pargstr ("EDGE") + else + call pargstr ("FLIPPED") + call printf ("SCANSPEED = %d ") + call pargl (P_SCANSPEED(parameters)) + call printf ("SCANORIGIN = %d ") + call pargl (P_SCANORIGIN(parameters)) + call printf ("CORNER = %d\n") + call pargl (P_CORNER(parameters)) + call printf ("DX = %d ") + call pargl (P_DX(parameters)) + call printf ("XTRAVEL = %d ") + call pargl (P_XTRAVEL(parameters)) + call printf ("XCOORD = %d\n") + call pargl (P_XCOORD(parameters)) + call printf ("DY = %d ") + call pargl (P_DY(parameters)) + call printf ("YTRAVEL = %d ") + call pargl (P_YTRAVEL(parameters)) + call printf ("YCOORD = %d\n") + call pargl (P_YCOORD(parameters)) +end diff --git a/noao/mtlocal/pds/pds_rimage.x b/noao/mtlocal/pds/pds_rimage.x new file mode 100644 index 00000000..13fd6309 --- /dev/null +++ b/noao/mtlocal/pds/pds_rimage.x @@ -0,0 +1,74 @@ + +include <imhdr.h> +include <mach.h> +include "rpds.h" + + +# PDS_READ_IMAGE -- Read PDS image pixels to IRAF image file + +procedure pds_read_image (pds_fd, im, parameters) + +int pds_fd +pointer im +long parameters[LEN_PAR_ARRAY] + +short linemin, linemax +int i, nlines +pointer buf +long v[IM_MAXDIM] + +int pds_init_read_scan(), pds_read_scan(), impnls() +long clktime() + +errchk impnls, pds_init_read_scan, pds_read_scan + +include "rpds.com" + +begin + call pds_set_image_header (im) + + if (NAXIS(im) == 0) + return + + IRAFMAX(im) = -MAX_REAL + IRAFMIN(im) = MAX_REAL + + call amovkl (long(1), v, IM_MAXDIM) + + nlines = NLINES(im) + + # PDS data is converted to type SHORT. + i= pds_init_read_scan (parameters) + + do i = 1, nlines { + if (impnls (im, buf, v) == EOF) + call error (3, "Error writing PDS data") + if (pds_read_scan (pds_fd, Mems[buf]) != NCOLS(im)) + call error (4, "Error reading PDS data") + call alims (Mems[buf], NCOLS(im), linemin, linemax) + IRAFMAX(im) = max (IRAFMAX(im), real (linemax)) + IRAFMIN(im) = min (IRAFMIN(im), real (linemin)) + } + + LIMTIME(im) = clktime (long(0)) +end + + +# PDS_SET_IMAGE_HEADER -- Set remaining header fields not set in read_header. + +procedure pds_set_image_header (im) + +pointer im + +include "rpds.com" + +begin + # Set IRAF image pixel type + if (data_type == ERR) { + if (BITPIX <= SZ_SHORT * SZB_CHAR * NBITS_BYTE) + IM_PIXTYPE(im) = TY_SHORT + else + IM_PIXTYPE(im) = TY_LONG + } else + IM_PIXTYPE(im) = data_type +end diff --git a/noao/mtlocal/pds/pds_rpixels.x b/noao/mtlocal/pds/pds_rpixels.x new file mode 100644 index 00000000..2f3371d4 --- /dev/null +++ b/noao/mtlocal/pds/pds_rpixels.x @@ -0,0 +1,182 @@ +include <mii.h> +include <mach.h> +include "rpds.h" + +# PDS_INIT_READ_SCAN -- A single PDS scan consists of one or more physical +# records. Each scan begins with a 10 byte scan start parameter. +# A "full" record will contain p_npts_per_rec data points, usually +# set equal to 2000. The last record may be short. +# If the number of records per scan is 1, the first record +# may also be shorter than p_npts_per_record. +# If the input tape is 7 track the actual number of points on the tape +# is rounded up to an integral multiple of 5. +# The input parameters of the procedure are an array of parameters of +# type long which are derived from the PDS header. The routine +# calculates the sizes of the records in chars, allocates the space +# required to hold the record buffer, and initializes the line count. + +# PDS_READ_SCAN -- Reads an entire PDS scan a record at a time. This procedure +# uses the MII unpack routine which is machine dependent. The bitpix +# must correspond to an MII type. The routine returns the number of +# data points per scan or EOF. READ_SCAN converts the 12 or 10 bit data +# values to short integers and flips every other scan if the PDS scan +# is a raster scan. + +int procedure pds_init_read_scan (parameters) + +long parameters[LEN_PAR_ARRAY] # array of header parameters + +# entry pds_read_scan (fd, scanbuf) + +int pds_read_scan() +int fd +short scanbuf[1] + +int maxbufsize, len_mii, linecount, temp +int npts_first, npts_full, npts_last +int sz_first, sz_full, sz_last +int p_npts_per_rec, p_npts_per_scan, p_nrecs_per_scan, p_scantype +int nrec, op, nchars +pointer mii + +int miilen(), pds_roundup(), read() + +errchk miilen, malloc, mfree, miiupk, read + +data mii/NULL/ + +include "rpds.com" + +begin + # Allocate sufficient space for the largest record in a scan + # Rounding up if the recordsize is not an integral number of chars. + + p_nrecs_per_scan = P_NRECS_PER_SCAN(parameters) + p_npts_per_scan = P_NPTS_PER_SCAN(parameters) + p_npts_per_rec = P_NPTS_PER_REC(parameters) + p_scantype = P_SCANTYPE(parameters) + temp = p_nrecs_per_scan + + maxbufsize = pds_roundup (SCANSTART + 2*p_npts_per_rec, SZB_CHAR) + maxbufsize = pds_roundup (maxbufsize, 2) / 2 + len_mii = miilen (maxbufsize, MII_SHORT) + if (mii != NULL) + call mfree (mii, TY_INT) + call malloc (mii, len_mii, TY_INT) + + # Calculate the number of data points, and the number of chars + # in a first, full and last record rounding up if the record is + # not an integral number of chars + + linecount = 1 + npts_first = min (p_npts_per_scan, p_npts_per_rec) + if (ninetrack == NO) { + sz_first = pds_roundup (npts_first, SCANSTART/2) + sz_first = pds_roundup (2*sz_first + SCANSTART, SZB_CHAR) / SZB_CHAR + } else + sz_first = pds_roundup (2*npts_first + SCANSTART, + SZB_CHAR) / SZB_CHAR + npts_full = p_npts_per_rec + sz_full = pds_roundup (npts_full*2, SZB_CHAR) / SZB_CHAR + npts_last = mod (p_npts_per_scan, p_npts_per_rec) + if (ninetrack == NO) { + sz_last = pds_roundup (npts_last, SCANSTART/2) + sz_last = pds_roundup (2*sz_last, SZB_CHAR) / SZB_CHAR + } else + sz_last = pds_roundup (2*npts_last, SZB_CHAR) / SZB_CHAR + + return (OK) + +entry pds_read_scan (fd, scanbuf) + + op = 1 + + # Loop over the number of records in a scan + do nrec = 1, temp { + + # Get 1st record, remove the 10 bytes containing the scan start + # parameter, and unpack the data. + if (nrec == 1) { + nchars = read (fd, Memi[mii], sz_first) + if (nchars == EOF) + return (EOF) + else if (nchars < sz_first) + call error (6, "Short record encountered.") + call bytmov (Memi[mii], SCANSTART + 1, Memi[mii], 1, + npts_first*2) + call miiupk (Memi[mii], scanbuf[op], npts_first, + MII_SHORT, TY_SHORT) + op = op + npts_first + + # Get last record which may be short + } else if (nrec == p_nrecs_per_scan) { + nchars = read (fd, Memi[mii], sz_last) + if (nchars == EOF) + return (EOF) + else if (nchars < sz_last) + call error (6, "Short record encountered.") + call miiupk (Memi[mii], scanbuf[op], npts_last, + MII_SHORT, TY_SHORT) + op = op + npts_last + + # Get a full record + } else { + nchars = read (fd, Memi[mii], sz_full) + if (nchars == EOF) + return (EOF) + else if ( nchars < sz_full) + call error (6, "Short record encountered.") + call miiupk (Memi[mii], scanbuf[op], npts_full, + MII_SHORT, TY_SHORT) + op = op + npts_full + } + } + + # Convert PDS 10 or 12 bit values to short SPP values + call pds_apdp8s (scanbuf, scanbuf, p_npts_per_scan) + + # If the image is a raster scan flip every other line + if (p_scantype == RASTER && mod (linecount, 2) == 0) + call pds_aflips (scanbuf, p_npts_per_scan) + + linecount = linecount + 1 + return (op - 1) +end + + +# PDS_AFLIPS -- Procedure to flip a short vector in place + +procedure pds_aflips (buf, npix) + +short buf[npix] +int npix + +int n_total, n_half, i, j + +begin + n_half = npix/2 + n_total = npix + 1 + for (i=1; i <= n_half; i = i + 1) { + j = buf[i] + buf[i] = buf[n_total - i] + buf[n_total - i] = j + } +end + + +# PDS_ROUNDUP -- Procedure to round an integer to the next highest number +# divisible by base. + +int procedure pds_roundup (number, base) + +int number, base +int value + +begin + if (mod(number, base) == 0) + return (number) + else { + value = (number/base + 1) * base + return (value) + } +end diff --git a/noao/mtlocal/pds/rpds.com b/noao/mtlocal/pds/rpds.com new file mode 100644 index 00000000..ef62e4fa --- /dev/null +++ b/noao/mtlocal/pds/rpds.com @@ -0,0 +1,13 @@ +# PDS reader common + +int data_type # Output data type + +# Option flags +int make_image # Create an IRAF image +int long_header # Print a long PDSheader +int short_header # Print a short header (Title and size) +int tenbit # Specify tenbit data +int ninetrack # Specify ninetrack tape + +common /pdsreadcom/ data_type, make_image, long_header, short_header, tenbit, + ninetrack diff --git a/noao/mtlocal/pds/rpds.doc b/noao/mtlocal/pds/rpds.doc new file mode 100644 index 00000000..b2a3f244 --- /dev/null +++ b/noao/mtlocal/pds/rpds.doc @@ -0,0 +1,83 @@ +PDSREAD (dataio) PDS Reader PDSREAD (dataio) + + + +NAME + pdsread -- Convert Kitt Peak PDS image files to IRAF image files + + +USAGE + pds [pds_file, file_list, iraf_file] + + +DESCRIPTION + Kitt Peak PDS format image data is read from the specified source, + either a disk file or magnetic tape. The PDS header may + optionally be printed on the standard output as either a full + listing or a short description. Image data may optionally be + converted to an IRAF image of specified data type. + + +PARAMETERS + + pds_file + The PDS data source. If the data source is a disk file or an + explict tape file specification of the form mt*[n] where n is + a file number then only that file is converted. If the + general tape device name is given, i.e. mta, mtb800, etc, + then the files specified by the files parameter will be read + from the tape. + + file_list + The files to be read from a tape are specified by the + file_list string. The string can consist of any sequence of + file numbers separated by at least one of whitespace, comma, + or dash. A dash specifies a range of files. For example the + string + + 1 2, 3 - 5,8-6 + + will convert the files 1 through 8. + + iraf_file + The IRAF file which will receive the PDS data if the + read_image parameter switch is set. For tape files specified + by the file_list parameter the filename will be used as a + prefix and the file number will be appended. Otherwise, the + file will be named as specified. Thus, reading files 1 and 3 + from a PDS tape with a filename of data will produce the + files data1 and data3. It is legal to use a null filename. + + read_image + This switch determines whether PDS image data is converted to + + + -1- +PDSREAD (dataio) PDS Reader PDSREAD (dataio) + + + + an IRAF image file. This switch is set to no to obtain just + header information with the long_header or short_header + switches. + + long_header + If this switch is set the full PDS header is printed on the + standard output. + + short_header + If this switch is set only the output filename, the title + string, and the image dimensions are printed. + + standard_format + The PDS standard format has the most significant byte first. + + data_type + The IRAF image file may be of a different data type than the + PDS image data. The data type may be specified as s for + short, l for long, and r for real. The user must beware of + truncation problems if an inappropriate data type is + specified. If an incorrect data_type or a null string is + given for this parameter then a default data type is used + which is the appropriate minimum size for the input pixel + values. diff --git a/noao/mtlocal/pds/rpds.h b/noao/mtlocal/pds/rpds.h new file mode 100644 index 00000000..33c7c673 --- /dev/null +++ b/noao/mtlocal/pds/rpds.h @@ -0,0 +1,88 @@ + +# PDS Definitions + +# The PDS standard readable by the PDS reader: +# +# 1. 8 bits / byte +# 2. 6 bits of data / byte +# 3. high order byte is first +# 4. first 80 bytes are an id string in 059 code containing 40 characters +# 12 bits per character +# 5. remaining 40 bytes contain short and long parameter values +# +# A user specified flag allows selecting most significant byte format + +define BITPIX 16 # Number of bits per PDS data value +define PDS_BYTE 8 # Number of bits per PDS byte +define LEN_PDS_TEXT 40 # Length of PDS text in characters +define LEN_PDS_HEADER 120 # Length of PDS header in bytes +define LEN_TABLE 96 # Length of 059 to ASCII table +define LEN_PAR_ARRAY 14 # Length of paramter array +define SZB_MIISHORT 2 # Number of bytes in an MII short +define SZB_MIILONG 4 # Number of bytes in an MII long + +# Mapping of PDS Parameters to IRAF image header + +define NAXIS IM_NDIM($1) # Number of image dimensions +define NCOLS IM_LEN($1, 1) # Number of pixels in first dimension +define NLINES IM_LEN($1, 2) # Number of pixels in second dimension +define TITLE IM_TITLE($1) +define SZ_TITLE SZ_IMTITLE + +# define the IRAF coordinate tranformation parameters + +define CRVAL CT_CRVAL(IM_CTRAN($1), $2) +define CRPIX CT_CRPIX(IM_CTRAN($1), $2) +define CDELT CT_CDELT(IM_CTRAN($1), $2) +define CROTA CT_CROTA(IM_CTRAN($1), $2) +define CTYPE CT_CTYPE(IM_CTRAN($1)) + +# define remaining IRAF header parameters + +define IRAFMAX IM_MAX($1) +define IRAFMIN IM_MIN($1) +define LIMTIME IM_LIMTIME($1) +define PIXTYPE IM_PIXTYPE($1) + +# define scan types +define RASTER 210 +define EDGE 197 +define FLIPPED 198 + +# define the octal constants for conversion of signed parameters +define TWO_TO_23 40000000b +define TWO_TO_24 100000000b + +# define the byte offsets for the header parameters +define DX pds_unpacks ($1,81) # Delta x in microns of scan +define DY pds_unpackl ($1,83) # Delta y in microns of scan +define NPTS_PER_SCAN pds_unpackl ($1,87) # Number of scans +define NSCANS pds_unpacks ($1,91) # Number of scans +define SCANTYPE pds_unpacks ($1,93) # Edge, flipped or raster +define SCANSPEED pds_unpacks ($1,95) # Scanning speed (1-255) +define SCANORIGIN pds_unpacks ($1,97) # Origin of scan 1,2,3,4 or 0 +define CORNER pds_unpacks ($1,99) # Starting corner of scan +define NRECS_PER_SCAN pds_unpacks ($1,101) # Number of records per scan +define XTRAVEL pds_unpackl ($1,103) # Xtravel in microns per scan +define YTRAVEL pds_unpackl ($1,107) # Ytravel in microns per scan +define NPTS_PER_REC pds_unpacks ($1,111) # Number of points per record +define XCOORD pds_unpackl ($1,113) # X coordinate of origin +define YCOORD pds_unpackl ($1,117) # Y coordinate of origin + +# define the parameter array +define P_DX $1[1] +define P_DY $1[2] +define P_NPTS_PER_SCAN $1[3] +define P_NSCANS $1[4] +define P_SCANTYPE $1[5] +define P_SCANSPEED $1[6] +define P_SCANORIGIN $1[7] +define P_CORNER $1[8] +define P_NRECS_PER_SCAN $1[9] +define P_XTRAVEL $1[10] +define P_YTRAVEL $1[11] +define P_NPTS_PER_REC $1[12] +define P_XCOORD $1[13] +define P_YCOORD $1[14] + +define SCANSTART 10 # Number of bytes in the scanstart indicator diff --git a/noao/mtlocal/pds/structure.doc b/noao/mtlocal/pds/structure.doc new file mode 100644 index 00000000..5a560f35 --- /dev/null +++ b/noao/mtlocal/pds/structure.doc @@ -0,0 +1,105 @@ +PDSREAD (Program Structure) PDSREAD (Program Structure) + + + +PDS Structure Chart + +t_pdsread() +# Returns when file list is satified or if EOT is encountered. +# Errors from called routines are trapped and printed as a warning. + + read_pds + # Returns OK or EOF + + read_header + # Returns OK or EOF + + init_read_pixels + # Returns OK + + read_pixels + # Returns OK + + decode_header + + decode_text + + decode_parameters + + print_header + + read_image + + set_image_header + + init_read_pixels + + read_pixels + + + + +PDSREAD Structure Summary + + +t_pdsread + The main procedure reads the control parameters. The files to be + converted are calculated from the specified source and file list. + A loop through the files determines the specific input source + names and output filenames and calls READ_PDS for each conversion. + + read_pds + The input source is opened and the output header file is + + + -1- +PDSREAD (Program Structure) PDSREAD (Program Structure) + + + + created. If only the PDS header is to be listed then a + temporary image header file is created. The PDS header is + read and decoded into the IRAF image header by READ_HEADER. + If make_image is true then READ_IMAGE is called. Finally all + the files are closed. If a temporary image header file was + created it is deleted. + + read_header + The PDS header is read into an array of text and an an + array of parameters using INIT_READ_PIXEL and READ_PIXEL. + These arrays are passed to DECODE_HEADER and subsequently + printed on the standard output. The routine returns OK or + EOF. Errors are returned by the error handler. + + init_read_pixels + The pixel reading routine is initialized. + + read_pixels + The pixels are read into a record buffer. + + decode_header + Decodes the text portion of the header using + DECODE_TEXT and DECODE_PARAMETERS. + + decode_text + Converts the id string from 059 code to 8 bit + ASCII. + + decode_parameters + Decodes the PDS scan parameters. + + print_header + If the short_header switch is set then the image title + and size are printed. If the long_header switch is + set then all the header information is printed. + + read_image + The PDS image pixels are converted to an IRAF image file. + The image file header is set using SET_IMAGE_HEADER. The + lines of the image are converted one at a time. + + set_image_header + The pixel type for the IRAF image is set to the user + specified type. If no type has been specified then + the type is determined from the number of bits per + pixel given in pds.h. diff --git a/noao/mtlocal/pds/structure.hlp b/noao/mtlocal/pds/structure.hlp new file mode 100644 index 00000000..6bb2eab8 --- /dev/null +++ b/noao/mtlocal/pds/structure.hlp @@ -0,0 +1,85 @@ +.help pdsread 2 "Program Structure" +.sh +PDSREAD Structure Chart + +.nf +t_pdsread() +# Returns when file list is satisfied or if EOT is encountered. + + read_pds (pdsfile, iraffile) + # Returns OK or EOF + + read_header (pds_fd, im, parameters) + # Returns OK or EOF + + read_image (pds_fd, im, parameters) + + set_image_header (im) + + init_read_scan (parameters) + # Returns OK + + read_scan (fd, scanbuf) + # Returns EOF or number of points in a scan +.fi + +.sh +PDSREAD Structure Summary + +.ls t_pdsread +The main procedure reads the control parameters. +The files to be read and converted are calculated from the specified source +and file list. +A loop through the files determines the specific input source names and +output file names and calls READ_PDS for each conversion. +.ls read_pds +The input source is opened and the output image header file is created. +If only the PDS header is to be listed then a temporary image header +file is created. The PDS header is read and decoded into the IRAF +image header bye READ_HEADER. If the image is to be read then +READ_IMAGE is called. Finally all files are closed. If a temporary +image file was created it is deleted. +.ls read_header +The 120 byte PDS header is read into an integer array. The ID string +in the first 80 bytes is unpacked into a text string using the MIIUP routine +and stored in the IRAF image header. The 12 bit PDP values are converted to +SPP short data valuese using the routine APDP8S. +The PDP 059 text code is converted to ASCII using the routine APDP059. +The remaining header quantities are unpacked into short +or long SPP integers using the MIIUP, APDP8S, UNPACKS and UNPACKL and +the image dimensions are stored in the IRAF image header. +Finally the PRINT_HEADER is called to print a long or short version of the +header. +.le +.ls read_image +The PDS image pixels are converted to an IRAF image file. +The image file header is set. +The lines of the image are converted one at a time. +.ls set_image_header +The pixel type for the IRAF image is set to the user specified type. +If no type has been specified then the type is determined from the +number of bits per pixel given in pds.h. +.le +.ls init_read_scan +Initializes the scan parameters. Input is a long integer array containing +the decoded header parameters. The procedure uses the number of data points +per scan, the number of records per scan and the number of points per full +records, calculates and allocates the buffer space required and determines +the size of each record in chars. If the tape is an old 7 track tape the +size of the record must be rounded up till it holds an integral number +of Cyber words in length. For example a record containing 1001 real data +points will actually be 1005 data points long with junk in the last 4 spaces. +.le +.ls read_scan +Reads an entire PDS scan a record at a time looping over the number of +records per scan. The procedure uses the MIIUP +routine which is machine dependent. The bitpix must correspond to +an MII type. READ_SCAN returns the number of data points per scan or EOF. +READ_SCAN calls APDP8S to convert the 10 or 12 bit data values to short +integers and calls AFLIPS to flip every other scan if the PDS scan +is a raster scan. +.le +.le +.le +.le +.endhelp diff --git a/noao/mtlocal/pds/t_pdsread.x b/noao/mtlocal/pds/t_pdsread.x new file mode 100644 index 00000000..94b13320 --- /dev/null +++ b/noao/mtlocal/pds/t_pdsread.x @@ -0,0 +1,127 @@ +include <error.h> +include <fset.h> + +# T_PDSREAD -- Read PDS format data. Further documentation given +# in pds.hlp + +define MAX_RANGES 100 + +procedure t_pdsread() + +char infile[SZ_FNAME] # the input file name list +char outfile[SZ_FNAME] # the output file name list +char file_list[SZ_FNAME] # the input file number list +int offset # the output file name offset + +char in_fname[SZ_FNAME], out_fname[SZ_FNAME] +int range[MAX_RANGES*2+1], nfiles, file_number, stat, junk +int lenlist +pointer list + +bool clgetb() +char clgetc() +int fstati(), btoi(), clgeti(), fntlenb(), fntgfnb(), mtfile() +int mtneedfileno() +int pds_read(), decode_ranges(), get_next_number(), pds_get_image_type() +pointer fntopnb() + +include "rpds.com" + +begin + # Set up the standard output to flush on a newline. + if (fstati (STDOUT, F_REDIR) == NO) + call fseti (STDOUT, F_FLUSHNL, YES) + + # Get the input file name(s). + call clgstr ("pds_file", infile, SZ_FNAME) + if (mtfile (infile) == YES) { + list = NULL + if (mtneedfileno (infile) == YES) + call clgstr ("file_list", file_list, SZ_LINE) + else + call strcpy ("1", file_list, SZ_LINE) + } else { + list = fntopnb (infile, YES) + lenlist = fntlenb (list) + call sprintf (file_list, SZ_LINE, "1-%d") + call pargi (lenlist) + } + + # Decode the ranges. + if (decode_ranges (file_list, range, MAX_RANGES, nfiles) == ERR) + call error (1, "Illegal file number list") + + # Setup the output options. + long_header = btoi (clgetb ("long_header")) + short_header = btoi (clgetb ("short_header")) + make_image = btoi (clgetb ("make_image")) + tenbit = btoi (clgetb ("tenbit")) + ninetrack = btoi (clgetb ("ninetrack")) + offset = clgeti ("offset") + + # Set the output image data type. + if (make_image == YES) { + data_type = pds_get_image_type (clgetc ("datatype")) + call clgstr ("iraf_file", outfile, SZ_FNAME) + } else + outfile[1] = EOS + + # Read successive PDS files, convert and write into a numbered + # succession of output IRAF files. + + file_number = 0 + while (get_next_number (range, file_number) != EOF) { + + # Get the input file name. + if (list != NULL) + junk = fntgfnb (list, in_fname, SZ_FNAME) + else { + if (mtneedfileno (infile) == YES) + call mtfname (infile, file_number, in_fname, SZ_FNAME) + else + call strcpy (infile, in_fname, SZ_FNAME) + } + + # Get the output file name. + if (nfiles > 1) { + call sprintf (out_fname[1], SZ_FNAME, "%s%03d") + call pargstr (outfile) + call pargi (file_number + offset) + } else + call strcpy (outfile, out_fname, SZ_FNAME) + + # Convert PDS file to the output IRAF file. If EOT is reached + # then exit. If an error is detected then print a warning and + # continue with the next file. + + iferr (stat = pds_read (in_fname, out_fname)) + call erract (EA_FATAL) + if (stat == EOF) # EOT found + break + } + + if (list != NULL) + call fntclsb (list) +end + +# GET_IMAGE_TYPE -- Convert a character to an IRAF image type. + +define NTYPES 7 + +int procedure pds_get_image_type(c) + +char c +int i, type_codes[NTYPES] +int stridx() + +string types "usilrds" # supported image data types +data type_codes /TY_USHORT, TY_SHORT, TY_INT, TY_LONG, TY_REAL, + TY_DOUBLE, TY_COMPLEX/ + +begin + i = stridx (c, types) + if (i == 0) + return (ERR) + else + return (type_codes[stridx (c, types)]) +end |