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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
include <ctype.h>
include <imhdr.h>
include "slitpic.h"
# T_SLITPIC -- generates image to be used as a mask for making aperture plates.
# Positions of slits have already been calculated and are read from "tape1".
# If the user wants to generate a dicomed print of the mask with crtpict, a
# command file to be used as input to task crtpict can be generated.
procedure t_slitpic ()
pointer im
char site[SZ_LINE], pix_date[SZ_LINE], output_root[SZ_FNAME], tape1[SZ_FNAME]
char serial_numbers[SZ_LINE], cmd_root[SZ_FNAME], cmd_file[SZ_FNAME]
char id_string[LEN_IDSTRING], suffix[SZ_LINE], image_name[SZ_FNAME]
int serial[3, MAX_RANGES], stat, find_slits(), jj, junk
int nserial, fd, this_number, n_slits, slits[MAX_SLITS, N_PARAMS]
real pixel_scale, plate_scale, slit_width
pointer immap()
bool clgetb()
int decode_ranges(), strncmp(), open(), itoc()
real clgetr()
begin
# Get parameters from cl
call clgstr ("site", site, SZ_LINE)
if (strncmp (site, "kpno", 1) == 0 || strncmp (site, "KPNO", 1) == 0)
plate_scale = PSCALE
else if (strncmp (site, "ctio",1) == 0 || strncmp (site, "CTIO",1) == 0)
plate_scale = CPSCALE
else {
call eprintf ("Unknown site: %s Try again.\n")
call pargstr (site)
return
}
call clgstr ("output_root", output_root, SZ_FNAME)
call clgstr ("pix_date", pix_date, SZ_LINE)
pixel_scale = clgetr ("pixel_scale")
slit_width = clgetr ("slit_width")
call clgstr ("tape1", tape1, SZ_FNAME)
fd = open (tape1, READ_ONLY, TEXT_FILE)
# Serial numbers to be processed are entered as a range.
call clgstr ("serial_numbers", serial_numbers, SZ_LINE)
if (decode_ranges (serial_numbers, serial, MAX_RANGES, nserial) == ERR)
call error (0, "Error in specifying range of serial numbers")
for (jj = 1; jj <= nserial; jj = jj + 1) {
stat = find_slits (fd, serial, pixel_scale, plate_scale,
slit_width, slits, n_slits, id_string, this_number)
if (stat == EOF)
return
# Generate unique output file names if more than one serial number
call strcpy (output_root, image_name, SZ_FNAME)
call strcpy (cmd_root, cmd_file, SZ_FNAME)
if (nserial > 1) {
junk = itoc (this_number, suffix, SZ_LINE)
call strcat (suffix, image_name, SZ_FNAME)
call strcat (suffix, cmd_file, SZ_FNAME)
}
im = immap (image_name, NEW_IMAGE, LEN_USER_AREA)
call strupr (pix_date)
call sprintf (IM_TITLE(im), SZ_LINE,
"SN=%d, SW=%0.2f, PS=%0.4f, PD=%s, %s")
call pargi (this_number)
call pargr (slit_width)
call pargr (pixel_scale)
call pargstr (pix_date)
call pargstr (id_string)
call write_image (im, slits, n_slits, plate_scale, pixel_scale)
if (clgetb ("crtpict"))
call write_crtpict_cards (cmd_file, site, this_number,
slit_width, image_name, pixel_scale, pix_date)
call imunmap (im)
}
end
int procedure find_slits (fd, serial, pixel_scale, plate_scale, slit_width,
slits, n_slits, id_string, this_number)
int fd
int serial[ARB]
int slits[MAX_SLITS, N_PARAMS]
real slit_width
int this_number
char keyword[LEN_KEYWORD], card_image[SZ_LINE], equal[LEN_KEYWORD]
char id_string[LEN_IDSTRING]
int serial_number, i, n_slits, ip, dummy, limit, j, jnext
real xpos_lo, xpos_hi, ypos, pixel_scale, plate_scale
bool streq(), is_in_range()
int fscan(), ctor()
begin
# Read card images until a SERIAL keyword is found:
repeat {
if (fscan (fd) == EOF)
return (EOF)
call gargwrd (keyword, LEN_KEYWORD)
if (streq (keyword, "SERIAL")) {
call gargwrd (equal, LEN_KEYWORD)
call gargi (serial_number)
call printf ("Serial number %d seen\n")
call pargi (serial_number)
call flush (STDOUT)
if (is_in_range (serial, serial_number)) {
this_number = serial_number
break
}
}
}
# Now positioned at proper entry, find NS2 keyword and slit locations:
# This assumes keyword OBJECT always preceedes NS2.
repeat {
if (fscan (fd) == EOF)
return (EOF)
call gargwrd (keyword, LEN_KEYWORD)
if (streq (keyword, "OBJECT")) {
call gargwrd (equal, LEN_KEYWORD)
call gargwrd (id_string, LEN_IDSTRING)
next
}
if (streq (keyword, "NS2")) {
call gargwrd (equal, LEN_KEYWORD)
call gargi (n_slits)
break
}
}
do i = 1, n_slits {
if (fscan (fd) == EOF)
return (EOF)
else
call gargstr (card_image, SZ_LINE)
ip = START_COLUMN
dummy = ctor (card_image, ip, xpos_lo)
ip = ip + 8
dummy = ctor (card_image, ip, xpos_hi)
dummy = ctor (card_image, ip, ypos)
call calculate_slit_pos (xpos_lo, xpos_hi, ypos, slits, i,
pixel_scale, plate_scale, slit_width)
}
# Sort slits array in order of increasing x - bubble sort
for (limit = n_slits - 1; limit >= 1; limit = limit - 1) {
do j = 1, limit {
jnext = j + 1
if (slits [j,2] >= slits [jnext, 2])
call swap (jnext, j, slits)
}
}
end
# CALCULATE_SLIT_POS -- calculate position of slit and store results
# in array "slits". This procedure is called once for each slit.
procedure calculate_slit_pos (xplo, xphi, yp, slits, slit_num, pixel_scale,
plate_scale, slit_width)
real xplo, xphi, yp
int slits[MAX_SLITS, N_PARAMS], slit_num
int x_lo, x_hi, ycen, ys, y_lo, y_hi
int upper_ys, lower_ys
real pixel_scale, plate_scale, slit_width
begin
x_lo = int ((XY_ZERO_PT + xplo) / pixel_scale * plate_scale + 0.5) + 1
x_hi = int ((XY_ZERO_PT + xphi) / pixel_scale * plate_scale + 0.5) - 1
ycen = int ((XY_ZERO_PT + yp) / pixel_scale * plate_scale + 0.5)
ys = int ((slit_width / pixel_scale) + 0.5)
# The following 4 statements were added june25,1985 at Jim's request,
# and are intended to correct for rounding problems with slit width.
lower_ys = ys / 2
upper_ys = lower_ys
if ((ys - lower_ys) > lower_ys)
upper_ys = lower_ys + 1
# Next 2 statements modified at time of above change
#y_lo = ycen - ys
#y_hi = ycen + ys - 1
y_lo = ycen - lower_ys
y_hi = ycen + upper_ys - 1
slits [slit_num, 1] = slit_num
slits [slit_num, 2] = x_lo
slits [slit_num, 3] = x_hi
slits [slit_num, 4] = y_lo
slits [slit_num, 5] = y_hi
end
# SWAP -- swaps entries in input array; used for bubble sort.
procedure swap (new, old, slits)
int new, old # New and old indices to be swapped
int slits [MAX_SLITS, N_PARAMS] # Array of slit endpoints and index
int n
real temp[N_PARAMS]
begin
do n = 1, N_PARAMS {
temp[n] = slits [new, n]
slits [new, n] = slits [old, n]
slits [old, n] = temp[n]
}
end
# WRITE_IMAGE -- writes two dimensional image of slit mask. Slits and the
# area outside the circular field are clear; other mask areas are saturated.
# All pixel values are either clear (0) or saturated (255).
procedure write_image (im, slits, n_slits, plate_scale, pixel_scale)
pointer im, sp, row
int slits[MAX_SLITS, N_PARAMS]
int n_slits
real plate_scale, pixel_scale
int center, size, n, mask_radius, edge_1, edge_2, k, i
pointer impl2s()
begin
# First, set some image header parameters
call smark (sp)
size = int ((XY_ZERO_PT * 2.0 * plate_scale / pixel_scale) + 2.0 + 0.5)
call salloc (row, size, TY_SHORT)
IM_PIXTYPE(im) = TY_SHORT
IM_LEN(im, 1) = size
IM_LEN(im, 2) = size
center = (size / 2) + 1
do n = 1, size {
mask_radius = int (sqrt (real ((center**2) - ((center - n)**2))))
edge_1 = center - mask_radius
edge_2 = center + mask_radius
do i = 1, edge_1 - 1
Mems[row+i-1] = CLEAR
do i = edge_2 + 1, size
Mems[row+i-1] = CLEAR
do i = edge_1, edge_2
Mems[row+i-1] = SATURATE
do i = 1, n_slits {
if ((n >= slits[i,2]) && (n <= slits[i,3])) {
# Set slitlet area to 0
edge_1 = slits [i, 4]
edge_2 = slits [i, 5]
do k = edge_1, edge_2 - 1
Mems[row+k-1] = CLEAR
}
}
# Now output accumulated row to IRAF image
call amovs (Mems[row], Mems[impl2s(im, n)], size)
}
call sfree (sp)
end
procedure write_crtpict_cards (cmd_file, site, this_number, slit_width,
image_name, pixel_scale, date)
char cmd_file[SZ_FNAME], site[SZ_LINE], image_name[SZ_FNAME], date[SZ_LINE]
int this_number
real slit_width, pixel_scale
begin
# Generate command cards for execution of crtpict
end
|