aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/tbfrcd.x
blob: 894dbc19ba8fa643595f8d442211d702c41ca228 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
include <tbset.h>
include "tbtables.h"
include "tblfits.h"

# tbfrcd -- read all column descriptors
# For a FITS table, this routine reads the information describing all
# columns, and it assigns values to the column descriptors.  Memory
# for the column descriptors is assumed to already have been allocated.
# (This is called by tbuopn.)
#
# Phil Hodge,  6-Jul-1995  Subroutine created
# Phil Hodge, 14-Apr-1998  Use strcpy instead of strpak or tbcftp for
#			column name, units, and print format.
# Phil Hodge,  7-Jun-1999  Use TB_SUBTYPE instead of TB_HDUTYPE.
# Phil Hodge,  5-Aug-1999  Rewrite so that it reads all column info
#		in one call, not just the info for a single column;
#		in tbfcd3, assign COL_NELEM.
# Phil Hodge, 23-Jun-2000  The first character of TSCALi & TZEROi was being
#		truncated.  Assign values to COL_TDTYPE, COL_TSCAL, COL_TZERO;
#		change default values of tscal & tzero to 1. & 0. respectively.

procedure tbfrcd (tp, cp, ncols)

pointer tp		# i: pointer to table descriptor
pointer cp[ARB]		# i: pointers to column descriptors
int	ncols		# i: number of columns in cp array
#--
pointer sp
pointer ttype		# scratch for column name
pointer tform		# scratch for column format
pointer tunit		# scratch for column unit
pointer tdisp		# scratch for display format
pointer tscal, tzero	# parameters for scaling from integer to floating
errchk	tbfcd1, tbfcd2, tbfcd3

begin
	if (ncols < 1)
	    return

	call smark (sp)
	call salloc (ttype, (SZ_FTTYPE+1)*ncols, TY_CHAR)
	call salloc (tform, (SZ_FTFORM+1)*ncols, TY_CHAR)
	call salloc (tunit, (SZ_FTUNIT+1)*ncols, TY_CHAR)
	call salloc (tdisp, (SZ_FTTYPE+1)*ncols, TY_CHAR)
	call salloc (tscal, ncols, TY_DOUBLE)
	call salloc (tzero, ncols, TY_DOUBLE)

	# Initialize these arrays to null or indef.
	call tbfcd1 (Memc[ttype], Memc[tform], Memc[tunit], Memc[tdisp],
		Memd[tscal], Memd[tzero], ncols)

	# Read each keyword in the header, and assign values to these
	# arrays as keywords are found.
	call tbfcd2 (tp,
		Memc[ttype], Memc[tform], Memc[tunit], Memc[tdisp],
		Memd[tscal], Memd[tzero], ncols)

	# Loop over columns, interpret info from these arrays, and
	# assign to column descriptors.
	call tbfcd3 (tp, cp,
		Memc[ttype], Memc[tform], Memc[tunit], Memc[tdisp],
		Memd[tscal], Memd[tzero], ncols)

	call sfree (sp)
end

# This routine initializes the array values to null or INDEFD.

procedure tbfcd1 (ttype, tform, tunit, tdisp,
		tscal, tzero, ncols)

char	ttype[SZ_FTTYPE,ncols]	# o: will be initialized to null
char	tform[SZ_FTFORM,ncols]	# o: will be initialized to null
char	tunit[SZ_FTUNIT,ncols]	# o: will be initialized to null
char	tdisp[SZ_FTTYPE,ncols]	# o: will be initialized to null
double	tscal[ncols]		# o: will be initialized to 1.
double	tzero[ncols]		# o: will be initialized to 0.
int	ncols			# i: size of arrays
#--
int	col

begin
	do col = 1, ncols {
	    ttype[1,col] = EOS
	    tform[1,col] = EOS
	    tunit[1,col] = EOS
	    tdisp[1,col] = EOS
	    tscal[col] = 1.d0
	    tzero[col] = 0.d0
	}
end

# This routine reads each header record, checks whether the keyword is one
# of the those that define a column, and if so, extracts the information
# to the appropriate output array.

procedure tbfcd2 (tp,
		ttype, tform, tunit, tdisp,
		tscal, tzero, ncols)

pointer tp			# i: pointer to table descriptor
char	ttype[SZ_FTTYPE,ncols]	# o: will be assigned if keyword found
char	tform[SZ_FTFORM,ncols]	# o: will be assigned if keyword found
char	tunit[SZ_FTUNIT,ncols]	# o: will be assigned if keyword found
char	tdisp[SZ_FTTYPE,ncols]	# o: will be assigned if keyword found
double	tscal[ncols]		# o: will be assigned if keyword found
double	tzero[ncols]		# o: will be assigned if keyword found
int	ncols			# i: size of arrays
#--
pointer sp
pointer buf			# scratch for header record
pointer value			# scratch for keyword value
pointer comment			# scratch for comment for keyword
double	x			# tscal or tzero
int	parnum			# loop index for keyword number
int	col			# column number, read from keyword name
int	ip, ctoi(), ctod()
int	strncmp(), strlen()
int	status			# = 0 is OK
errchk	tbferr

begin
	status = 0

	call smark (sp)
	call salloc (buf, SZ_FNAME, TY_CHAR)
	call salloc (value, SZ_FNAME, TY_CHAR)
	call salloc (comment, SZ_FNAME, TY_CHAR)

	# Read each keyword in the header.
	do parnum = 1, TB_NPAR(tp) {

	    # Read the record as a string.
	    call fsgrec (TB_FILE(tp), parnum, Memc[buf], status)
	    if (status != 0)
		call tbferr (status)

	    if (Memc[buf] != 'T')
		next

	    ip = 6		# first character of the column number
	    if (ctoi (Memc[buf], ip, col) < 1)
		next

	    # Reject keywords such as "TTYPE5X".
	    if (Memc[buf+ip-1] != ' ' && Memc[buf+ip-1] != '=')
		next

	    # Extract the value.
	    call fspsvc (Memc[buf], Memc[value], Memc[comment], status)
	    if (status != 0)
		call tbferr (status)

	    # Trim trailing and leading blanks and single quotes.
	    ip = strlen (Memc[value]) - 1	# zero indexed
	    while (Memc[value+ip] == ' ' || Memc[value+ip] == '\'') {
		Memc[value+ip] = EOS
		ip = ip - 1
	    }
	    ip = 0
	    while (Memc[value+ip] == ' ' || Memc[value+ip] == '\'')
		ip = ip + 1

	    # Check to see whether this is one of the keywords that we need,
	    # and if so, copy the value to the output array.
	    if (strncmp (Memc[buf], "TTYPE", 5) == 0) {
		call strcpy (Memc[value+ip], ttype[1,col], SZ_FTTYPE)

	    } else if (strncmp (Memc[buf], "TFORM", 5) == 0) {
		call strcpy (Memc[value+ip], tform[1,col], SZ_FTFORM)

	    } else if (strncmp (Memc[buf], "TUNIT", 5) == 0) {
		call strcpy (Memc[value+ip], tunit[1,col], SZ_FTUNIT)

	    } else if (strncmp (Memc[buf], "TDISP", 5) == 0) {
		call strcpy (Memc[value+ip], tdisp[1,col], SZ_FTTYPE)

	    } else if (strncmp (Memc[buf], "TSCAL", 5) == 0) {
		ip = 1
		if (ctod (Memc[value], ip, x) < 1)
		    call error (1, "can't interpret TSCAL keyword")
		tscal[col] = x

	    } else if (strncmp (Memc[buf], "TZERO", 5) == 0) {
		ip = 1
		if (ctod (Memc[value], ip, x) < 1)
		    call error (1, "can't interpret TZERO keyword")
		tzero[col] = x
	    }
	}

	call sfree (sp)
end

# This routine interprets the contents of the ttype, etc, arrays
# and assigns values to the column descriptors.

procedure tbfcd3 (tp, cp,
		ttype, tform, tunit, tdisp,
		tscal, tzero, ncols)

pointer tp			# i: pointer to table descriptor
pointer cp[ncols]		# i: pointers to column descriptors
char	ttype[SZ_FTTYPE,ncols]	# i: array of column names
char	tform[SZ_FTFORM,ncols]	# i: array that defines data types
char	tunit[SZ_FTUNIT,ncols]	# i: array of column units
char	tdisp[SZ_FTTYPE,ncols]	# i: array of print formats
double	tscal[ncols]		# i: array of tscal values
double	tzero[ncols]		# i: array of tzero values
int	ncols			# i: size of arrays
#--
char	pform[SZ_COLFMT]	# print format for column
int	col			# loop index for column number
errchk	tbftya, tbftyb

begin
	do col = 1, ncols {

	    # If there's no column name, assign a default.
	    if (ttype[1,col] == EOS) {
		call sprintf (ttype[1,col], SZ_FTTYPE, "c%d")
		    call pargi (col)
	    }

	    if (tform[1,col] == EOS)
		call error (1, "TFORM not specified; this keyword is required")

	    # Determine the data type, print format and array length.
	    if (TB_SUBTYPE(tp) == TBL_SUBTYPE_ASCII) {

		call tbftya (tform[1,col], tdisp[1,col],
			tscal[col], tzero[col],
			COL_TDTYPE(cp[col]), COL_DTYPE(cp[col]),
			pform, SZ_COLFMT, COL_LEN(cp[col]))
		COL_NELEM(cp[col]) = 1		# does not support arrays

	    } else if (TB_SUBTYPE(tp) == TBL_SUBTYPE_BINTABLE) {

		call tbftyb (tform[1,col], tdisp[1,col],
			tscal[col], tzero[col],
			COL_TDTYPE(cp[col]), COL_DTYPE(cp[col]),
			pform, SZ_COLFMT,
			COL_NELEM(cp[col]), COL_LEN(cp[col]))

	    } else {

		call error (1, "tbfrcd:  invalid HDU type")
	    }

	    # Assign values to column descriptor.

	    COL_NUMBER(cp[col]) = col
	    COL_OFFSET(cp[col]) = 0			# meaningless

	    COL_TSCAL(cp[col]) = tscal[col]
	    COL_TZERO(cp[col]) = tzero[col]

	    call strcpy (ttype[1,col], COL_NAME(cp[col]), SZ_COLNAME)
	    call strcpy (tunit[1,col], COL_UNITS(cp[col]), SZ_COLUNITS)
	    call strcpy (pform, COL_FMT(cp[col]), SZ_COLFMT)
	}
end