aboutsummaryrefslogtreecommitdiff
path: root/noao/mtlocal/pds
diff options
context:
space:
mode:
Diffstat (limited to 'noao/mtlocal/pds')
-rw-r--r--noao/mtlocal/pds/README1
-rw-r--r--noao/mtlocal/pds/mkpkg14
-rw-r--r--noao/mtlocal/pds/pds_read.x71
-rw-r--r--noao/mtlocal/pds/pds_rheader.x234
-rw-r--r--noao/mtlocal/pds/pds_rimage.x74
-rw-r--r--noao/mtlocal/pds/pds_rpixels.x182
-rw-r--r--noao/mtlocal/pds/rpds.com13
-rw-r--r--noao/mtlocal/pds/rpds.doc83
-rw-r--r--noao/mtlocal/pds/rpds.h88
-rw-r--r--noao/mtlocal/pds/structure.doc105
-rw-r--r--noao/mtlocal/pds/structure.hlp85
-rw-r--r--noao/mtlocal/pds/t_pdsread.x127
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