aboutsummaryrefslogtreecommitdiff
path: root/noao/mtlocal/cyber/t_ridsfile.x
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /noao/mtlocal/cyber/t_ridsfile.x
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'noao/mtlocal/cyber/t_ridsfile.x')
-rw-r--r--noao/mtlocal/cyber/t_ridsfile.x516
1 files changed, 516 insertions, 0 deletions
diff --git a/noao/mtlocal/cyber/t_ridsfile.x b/noao/mtlocal/cyber/t_ridsfile.x
new file mode 100644
index 00000000..c7179763
--- /dev/null
+++ b/noao/mtlocal/cyber/t_ridsfile.x
@@ -0,0 +1,516 @@
+include <mach.h>
+include <imhdr.h>
+include <fset.h>
+include <error.h>
+include "cyber.h"
+
+
+# T_RIDSFILE __ code for the DUMPF IDSFILE reader. IDS records in an IDSFILE
+# are read from a Cyber DUMPF tape and optionally converted to IRAF images.
+# IDS records are not written sequentially in the IDSFILE, so, each record
+# must be read and then checked against the list of "record_numbers" to
+# see if the user requested the record to be read. The procedure terminates
+# when the requested number of records has been read or EOF is encountered.
+# The IDS trailer information is printed in either a short or long form;
+# the pixel values can also be printed.
+
+procedure t_ridsfile()
+
+pointer sp, cp
+char in_fname[SZ_FNAME], dumpf_file[SZ_FNAME]
+int file_ordinal
+
+int mtfile(), clgeti(), get_data_type(), btoi()
+bool clgetb()
+char clgetc()
+
+begin
+ # Allocate space for the control parameter descriptor structure
+ call smark (sp)
+ call salloc (cp, LEN_CP, TY_STRUCT)
+
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get parameters from cl and generate input file name. If the input
+ # file is a tape, append the file_ordinal suffix, incremented by one
+ # to skip over the DUMPF tape label.
+
+ call clgstr ("dumpf_file", dumpf_file, SZ_FNAME)
+ if (mtfile (dumpf_file) == YES) {
+ file_ordinal = clgeti ("file_ordinal")
+ call mtfname (dumpf_file, file_ordinal + 1, in_fname, SZ_FNAME)
+ } else
+ call strcpy (dumpf_file, in_fname, SZ_FNAME)
+
+ LONG_HEADER(cp) = btoi (clgetb ("long_header"))
+ PRINT_PIXELS(cp) = btoi (clgetb ("print_pixels"))
+ call clgstr ("record_numbers", REC_NUMBERS(cp), SZ_LINE)
+
+ # If an output image is to be written, get root output file name and
+ # output data type.
+ MAKE_IMAGE(cp) = btoi (clgetb ("make_image"))
+ if (MAKE_IMAGE(cp) == YES) {
+ call clgstr ("iraf_file", IRAF_FILE(cp), SZ_FNAME)
+ DATA_TYPE(cp) = get_data_type (clgetc ("data_type"))
+ if (DATA_TYPE(cp) == ERR)
+ DATA_TYPE(cp) = TY_REAL
+ }
+ call read_idsfile (in_fname, cp)
+
+ call sfree (sp)
+end
+
+
+# READ_IDSFILE -- read and sort the index of record ranges. Call
+# idsf_read_record for each record in each index range.
+
+procedure read_idsfile (in_fname, cp)
+
+char in_fname[SZ_FNAME] # Name of input file
+pointer cp # Pointer to control parameter structure
+
+int records[3, MAX_RANGES], nrecs, i
+pointer sp, pft, pru_buf
+int fd, junk, index_buf[LEN_INDEX * NINT_CYBER_WRD], nranges, nids_read
+int current_pru, n_index, next_pru, nrecords_to_read, npru_skip, n_rec
+long sorted_index[LEN_INDEX]
+
+int mtopen(), get_cyber_words_init(), read_dumpf_init(), read_dumpf()
+int get_cyber_words(), idsf_read_record(), decode_ranges()
+errchk mtopen, read_dumpf, get_cyber_words, idsf_read_record
+errchk sort_index, decode_ranges
+
+begin
+ # Allocate space for program data structure and buffers
+ call smark (sp)
+ call salloc (pft, NINT_CYBER_WRD * LEN_PFT, TY_INT)
+ call salloc (pru_buf, NINT_CYBER_WRD * LEN_PRU, TY_INT)
+
+ # Open and initialize the tape file, and read the permanent file table
+ fd = mtopen (in_fname, READ_ONLY, SZ_TAPE_BUFFER)
+ junk = get_cyber_words_init()
+ junk = read_dumpf_init()
+ if (get_cyber_words (fd, Memi[pft], LEN_PFT) == EOF) {
+ call printf ("DUMPF tape at EOT\n")
+ call sfree (sp)
+ call close (fd)
+ return
+ }
+
+ # Read and sort IDSFILE user index information. The first two
+ # pru's of this index are relevant. Up to 3 more pru's can
+ # follow, depending on the format of the idsfile. The code was
+ # modified 13Jan86 to read an old format tape of Paul Hintzen's
+ # and hopefully provide a general solution to the problem of
+ # different formats.
+
+ if (read_dumpf (fd, index_buf, LEN_USER_INDEX)== EOF) {
+ call close (fd)
+ call error (1, "Unexpected EOF when reading index")
+ }
+ if (decode_ranges (REC_NUMBERS(cp), records, MAX_RANGES, junk) == ERR)
+ call error (2, "Error in record_numbers specification")
+
+ call sort_index (index_buf, records, sorted_index, nranges, nrecs)
+
+ # Loop over each range of records in the index. nids_read counts
+ # the number of records requested by the user that have been read.
+ # nrecords_to_read is the number of records in the current index range.
+
+ nids_read = 0
+ current_pru = 3
+ for (n_index = 1; n_index <= nranges; n_index = n_index + 1) {
+ next_pru = sorted_index[n_index] / 1000
+ nrecords_to_read = mod (sorted_index[n_index], 1000)
+ npru_skip = next_pru - current_pru
+ do i = 1, npru_skip {
+ if (read_dumpf (fd, Memi[pru_buf], LEN_PRU) == EOF) {
+ # At end of IDSFILE
+ call printf ("DUMPF tape at EOF\n")
+ break
+ }
+ }
+
+ current_pru = current_pru + npru_skip
+
+ # Loop over each record within the current range of records
+ for (n_rec = 1; n_rec <= nrecords_to_read; n_rec = n_rec + 1) {
+ if (nids_read >= nrecs) {
+ # No need to continue
+ call close (fd)
+ call sfree (sp)
+ return
+ }
+
+ if (idsf_read_record (fd, records, nrecs, nids_read,
+ cp) == EOF) {
+ call close (fd)
+ call sfree (sp)
+ return
+ }
+
+
+ current_pru = current_pru + (LEN_IDS_RECORD / LEN_PRU)
+ }
+ }
+
+ call close (fd)
+ call sfree (sp)
+end
+
+
+# IDSF_READ_RECORD -- reads a single idsrecord. If the record is in the
+# set of records to be read, the record is processed and the count of requested
+# records read is incremented.
+
+int procedure idsf_read_record (fd, records, nrecs, nids_read, cp)
+
+int fd # File descriptor of input file
+int records[3, MAX_RANGES] # Array of ranges of records specified by user
+int nrecs # Number of requested records found on tape
+int nids_read # Number of requested records already read
+pointer cp # Pointer to control parameter structure
+
+char out_fname[SZ_FNAME]
+pointer sp, ids
+int ids_buffer[LEN_IDS_RECORD * NINT_CYBER_WRD], this_record
+int tape, scan
+real pixels[NPIX_IDS_RECORD]
+
+bool is_in_range()
+int read_dumpf(), bitupk(), strlen()
+errchk read_dumpf, read_header, idsf_write_image, list_values
+
+begin
+ # Allocate space for program data structure
+ call smark (sp)
+ call salloc (ids, LEN_IDS, TY_STRUCT)
+
+ # Read the next ids record
+ if (read_dumpf (fd, ids_buffer, LEN_IDS_RECORD) == EOF) {
+ # At end of IDSFILE
+ call printf ("DUMPF tape at EOF\n")
+ call sfree (sp)
+ return (EOF)
+ }
+
+ scan = bitupk (ids_buffer, SCAN_OFFSET, NBITS_INT)
+ tape = bitupk (ids_buffer, TAPE_OFFSET, NBITS_INT)
+ this_record = (tape * 1000) + scan
+ if (is_in_range (records, this_record)) {
+ nids_read = nids_read + 1
+ RECORD_NUMBER(ids) = this_record
+ iferr {
+ call calloc (COEFF(ids), MAX_COEFF, TY_DOUBLE)
+ call idsf_read_header (ids_buffer, ids)
+ } then {
+ call erract (EA_WARN)
+ call mfree (COEFF(ids), TY_DOUBLE)
+ call sfree (sp)
+ return (ERR)
+ }
+
+ call print_header (ids, LONG_HEADER(cp))
+
+ if (MAKE_IMAGE(cp) == YES) {
+ call strcpy (IRAF_FILE(cp), out_fname, SZ_FNAME)
+ call sprintf (out_fname[strlen(out_fname) + 1], SZ_FNAME, ".%d")
+ call pargi (RECORD_NUMBER(ids))
+ iferr {
+
+ call idsf_write_image (ids_buffer, DATA_TYPE(cp),
+ PRINT_PIXELS(cp), out_fname, ids)
+
+ } then {
+ call ERRACT (EA_WARN)
+ call mfree (COEFF(ids), TY_DOUBLE)
+ call sfree (sp)
+ return (ERR)
+ }
+ }
+
+ if (PRINT_PIXELS(cp) == YES && MAKE_IMAGE(cp) == NO) {
+ call unpk_30 (ids_buffer, 1, pixels, NPIX_IDS_RECORD)
+ call list_values (pixels)
+ }
+ call mfree (COEFF(ids), TY_DOUBLE)
+ }
+
+ call sfree (sp)
+ return (OK)
+end
+
+
+# SORT_INDEX -- Sort index information that precedes each IDSFILE. This
+# index occupies 5 PRU's and points to ranges of records. Each index
+# entry contains a PRU number and the low and high record numbers of the
+# records that begin at the stated PRU. These three pieces of information
+# are stored in a single 60-bit Cyber word. The number of records requested
+# by the user that are actually in the IDSFILE is also counted. This
+# number is returned as a parameter to the calling procedure.
+
+procedure sort_index (index_buf, records, sorted_index, nranges, nrecs_on_tape)
+
+int index_buf[ARB] # Buffer containing IDS index information
+int records[3, MAX_RANGES] # Array of ranges of records specified by user
+long sorted_index[LEN_INDEX] # Returned array of sorted index information
+int nranges # Number of ranges of IDS records in IDSFILE
+int nrecs_on_tape # Number of requested records actually on tape
+
+int i, start_pru, low_record_number, high_record_number, nrecs, j
+long index[LEN_INDEX]
+bool is_in_range()
+int bitupk()
+errchk asrtl, bitupk
+
+begin
+ nrecs_on_tape = 0
+ nranges = 0
+ do i = 1, NINT_CYBER_WRD * LEN_USER_INDEX, NINT_CYBER_WRD {
+ start_pru = bitupk (index_buf[i], NPRU_OFFSET, NBITS_NPRU)
+ if (start_pru == 0)
+ next
+ low_record_number = bitupk (index_buf[i], LRN_OFFSET, NBITS_LRN)
+ high_record_number = bitupk (index_buf[i], HRN_OFFSET, NBITS_HRN)
+ nrecs = high_record_number - low_record_number + 1
+ nranges = nranges + 1
+ index[nranges] = real (start_pru * 1000) + nrecs
+
+ for (j=low_record_number; j<=high_record_number; j=j+1) {
+ if (is_in_range (records, j))
+ nrecs_on_tape = nrecs_on_tape + 1
+ }
+ }
+
+ call asrtl (index, sorted_index, nranges)
+end
+
+
+# LIST_VALUES -- Print the ids pixel values.
+
+procedure list_values (pixel_buf)
+
+real pixel_buf[NPIX_IDS_RECORD] # Buffer containing pixels to be listed
+int n_pix
+
+begin
+ for (n_pix = 1; n_pix <= NPIX_IDS_RECORD; n_pix = n_pix + 4) {
+ call printf ("%10.4e %10.4e %10.4e %10.4e\n")
+ call pargr (pixel_buf[n_pix])
+ call pargr (pixel_buf[n_pix + 1])
+ call pargr (pixel_buf[n_pix + 2])
+ call pargr (pixel_buf[n_pix + 3])
+ }
+ call printf ("\n")
+end
+
+# IDSF_READ_HEADER -- Decode ids header parameters from the input buffer and
+# fill the program data structure.
+
+procedure idsf_read_header (ids_buffer, ids)
+
+int ids_buffer[NINT_CYBER_WRD*LEN_IDS_RECORD] # Input IDSFILE buffer
+pointer ids # Pointer to program data structure
+
+int n_coeff, i
+char alpha[3]
+int bitupk()
+double convert_60bit_fp()
+errchk bitupk, unpk_60i, convert_60bit_fp, unpk_id, display_code
+
+begin
+ # Get unsigned integer parameters from header
+ ITM(ids) = bitupk (ids_buffer, ITM_OFFSET, NBITS_INT)
+ NP1(ids) = bitupk (ids_buffer, NP1_OFFSET, NBITS_INT)
+ NP2(ids) = bitupk (ids_buffer, NP2_OFFSET, NBITS_INT)
+ BEAM_NUMBER(ids) = bitupk (ids_buffer, BEAM_OFFSET, NBITS_INT)
+ SMODE(ids) = bitupk (ids_buffer, SMODE_OFFSET, NBITS_INT)
+ if (SMODE(ids) != 0) {
+ # Determine companion record number
+ if (BEAM_NUMBER(ids) == 1)
+ COMPANION_RECORD(ids) = RECORD_NUMBER(ids) - 1
+ else
+ COMPANION_RECORD(ids) = RECORD_NUMBER(ids) + 1
+ }
+ UT(ids) = bitupk (ids_buffer, UT_OFFSET, NBITS_INT)
+ ST(ids) = bitupk (ids_buffer, ST_OFFSET, NBITS_INT)
+
+ # The following integer parameters can be negative
+ call unpk_60i (ids_buffer, DF_OFFSET, DF_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, SM_OFFSET, SM_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, QF_OFFSET, QF_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, DC_OFFSET, DC_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, QD_OFFSET, QD_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, EX_OFFSET, EX_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, BS_OFFSET, BS_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, CA_OFFSET, CA_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, CO_OFFSET, CO_FLAG(ids), 1)
+ call unpk_60i (ids_buffer, OFLAG_OFFSET, OFLAG(ids), 1)
+
+ # If the dispersion flag (DF) is set, get the coeffecients. The pointer
+ # to the coeffecient array is stored in the structure ids.
+ if (DF_FLAG(ids) > -1) {
+ n_coeff = DF_FLAG(ids)
+ do i = 1, n_coeff {
+ Memd[COEFF(ids)+i-1] = convert_60bit_fp (ids_buffer,
+ (COEFF_OFFSET + (i - 1)) * 64 + 1)
+ }
+ }
+
+ # These header values converted from Cyber 60-bit floating point
+ HA(ids) = convert_60bit_fp (ids_buffer, HA_OFFSET)
+ AIRMASS(ids) = convert_60bit_fp (ids_buffer, AIR_OFFSET)
+ RA(ids) = convert_60bit_fp (ids_buffer, RA_OFFSET)
+ DEC(ids) = convert_60bit_fp (ids_buffer, DEC_OFFSET)
+ LAMBDA0(ids) = convert_60bit_fp (ids_buffer, LAM_OFFSET)
+ DELTA_LAMBDA(ids) = convert_60bit_fp (ids_buffer, DEL_OFFSET)
+
+ # The 3 character ALPHA_ID is stored in Cyber display code
+ call display_code (bitupk (ids_buffer, ALPHA1_OFFSET, NBITS_DC),
+ alpha[1])
+ call display_code (bitupk (ids_buffer, ALPHA2_OFFSET, NBITS_DC),
+ alpha[2])
+ call display_code (bitupk (ids_buffer, ALPHA3_OFFSET, NBITS_DC),
+ alpha[3])
+ call strcpy (alpha, ALPHA_ID(ids), NCHAR_ALPHA)
+
+ # The ids label is written in 7-bit ascii
+ call unpk_id (ids_buffer, IDS_ID_OFFSET, LABEL(ids))
+end
+
+
+# PRINT_HEADER -- print the ids header in either long or short mode.
+
+procedure print_header (ids, long_header)
+
+pointer ids # Pointer to program data structure
+int long_header # Print header in long format (YES/NO)?
+int i
+
+real value1, value2
+
+begin
+ if (long_header == YES) {
+ call printf ("RECORD = %d, label = \"%s\",\n")
+ call pargi (RECORD_NUMBER(ids))
+ call pargstr (LABEL(ids))
+
+ if (OFLAG(ids) == 1) {
+ call printf ("oflag = OBJECT, beam_number = %d, ")
+ call pargi (BEAM_NUMBER(ids))
+ } else if (OFLAG (ids) == 0) {
+ call printf ("oflag = SKY, beam_number = %d, ")
+ call pargi (BEAM_NUMBER(ids))
+ }
+ call printf ("alpha_ID = %s")
+ call pargstr (ALPHA_ID(ids))
+ if (SMODE(ids) != 0) {
+ call printf (", companion = %d,\n")
+ call pargi (COMPANION_RECORD(ids))
+ } else
+ call printf (",\n")
+
+ call printf ("airmass = %5.3f,%24tW0 = %0.3f,")
+ call pargd (AIRMASS(ids))
+ call pargd (LAMBDA0(ids))
+ call printf (" WPC = %0.3f, ITM = %d,\n")
+ call pargd (DELTA_LAMBDA(ids))
+ call pargi (ITM(ids))
+ call printf ("NP1 = %d, NP2 = %d,")
+ call pargi (NP1(ids))
+ call pargi (NP2(ids))
+
+ if (IS_INDEFI (UT(ids)))
+ value1 = INDEFR
+ else
+ value1 = real (UT(ids) / 3600.)
+
+ if (IS_INDEFI (ST(ids)))
+ value2 = INDEFR
+ else
+ value2 = real (ST(ids) / 3600.)
+ call printf (" UT = %h, ST = %h,\n")
+ call pargr (value1)
+ call pargr (value2)
+
+ call printf ("HA = %h,")
+ call pargd (HA(ids))
+ call printf (" RA = %h, DEC = %h,\n")
+ call pargd (RA(ids))
+ call pargd (DEC(ids))
+ call printf ("df = %d, sm = %d, qf = %d, dc = %d, qd = %d, ")
+ call pargi (DF_FLAG(ids))
+ call pargi (SM_FLAG(ids))
+ call pargi (QF_FLAG(ids))
+ call pargi (DC_FLAG(ids))
+ call pargi (QD_FLAG(ids))
+ call printf ("ex = %d, bs = %d, ca = %d, co = %d")
+ call pargi (EX_FLAG(ids))
+ call pargi (BS_FLAG(ids))
+ call pargi (CA_FLAG(ids))
+ call pargi (CO_FLAG(ids))
+
+ # The df coeffecients are printed out in the case where the df
+ # flag is set, and the first coefficient is nonzero. The later
+ # condition is a test for IDSOUT data, where the df coeffecients
+ # have been applied but not stored in the header.
+
+ if (DF_FLAG(ids) != -1 && COEFF(ids) != 0) {
+ call printf (",\n")
+ do i = 1, DF_FLAG(ids) {
+ call printf ("df[%d] = %10.8g")
+ call pargi(i)
+ call pargd(Memd[COEFF(ids)+i-1])
+ if (i != DF_FLAG(ids))
+ call printf (", ")
+ if (mod (i, 4) == 0)
+ call printf ("\n")
+ }
+ call printf ("\n")
+ } else
+ call printf ("\n")
+ call printf ("\n")
+ } else {
+ call printf ("RECORD = %d, label = \"%s\"\n")
+ call pargi (RECORD_NUMBER(ids))
+ call pargstr (LABEL(ids))
+ }
+end
+
+
+# IDSF_WRITE_IMAGE -- pixels are unpacked from the input buffer and written to
+# a one dimensional IRAF image.
+
+procedure idsf_write_image (ids_buffer, data_type, print_pixels, out_fname,
+ ids)
+
+int ids_buffer[NINT_CYBER_WRD * LEN_IDS_RECORD] # Input IDSFILE buffer
+int data_type # Data type of pixels to be written
+int print_pixels # List pixel values (YES/NO)?
+char out_fname[SZ_FNAME] # Name of output image
+pointer ids # Pointer to program data structure
+
+pointer im, pixels
+pointer impl1r(), immap()
+errchk immap, unpk_30, cy_store_keywords, imunmap
+
+begin
+ # Map new iraf image and set up image header
+ im = immap (out_fname, NEW_IMAGE, LEN_USER_AREA)
+ IM_NDIM(im) = 1
+ IM_LEN(im, 1) = NPIX_IDS_RECORD
+ call strcpy (LABEL(ids), IM_TITLE(im), SZ_IMTITLE)
+ IM_PIXTYPE(im) = data_type
+ pixels = impl1r(im)
+
+ # Convert pixels to spp reals and write image line
+ call unpk_30 (ids_buffer, 1, Memr[pixels], NPIX_IDS_RECORD)
+
+ if (print_pixels == YES)
+ call list_values (Memr[pixels])
+
+ # Write ids specific header words to iraf image header
+ call cy_store_keywords (ids, im)
+
+ call imunmap (im)
+end