

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(fd)
junk = read_dumpf_init(fd)
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
Source Code · Search Form · STSDAS
Maintained by the Science Software Group at STScI
This file last updated on 14 Jan 1993