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
|
include <imhdr.h>
include <error.h>
define MAX_NR_BEAMS 100 # Max number of instrument apertures
# T_FLATDIV -- Divide by a flat field spectrum. This is basically
# a simple division of two vectors but with the following
# additional functions:
#
# 1. Check the processing flag of the input spectra to avoid
# double processing, and set the flag if the processing is
# performed.
# 2. Trap division by zero errors
# 3. Optionally apply coincidence corrections
procedure t_flatdiv ()
int root, start_rec
int nrecs
int len_flat
int ccmode, qd_flag
real dtime
real power
bool coincidence
pointer sp, image, str, ofile, flat, recs, bstat, flatsp, im
int clpopni(), clgeti(), clgwrd(), imgeti()
int get_next_image(), decode_ranges()
real clgetr()
bool clgetb()
pointer immap()
errchk get_flatsp
begin
call smark (sp)
call salloc (image, SZ_FNAME, TY_CHAR)
call salloc (str, SZ_LINE, TY_CHAR)
call salloc (ofile, SZ_FNAME, TY_CHAR)
call salloc (flat, SZ_FNAME, TY_CHAR)
call salloc (recs, 300, TY_INT)
call salloc (bstat, MAX_NR_BEAMS, TY_INT)
# Open input file name template
root = clpopni ("input")
# Get range specification if any
call clgstr ("records", Memc[str], SZ_LINE)
if (decode_ranges (Memc[str], Memi[recs], 100, nrecs) == ERR)
call error (0, "Bad range specification")
# Get rootname for output files and starting record
# Subtract 1 from start_rec because 1 will be added later.
call clgstr ("output", Memc[ofile], SZ_FNAME)
start_rec = clgeti ("start_rec") - 1
# Get flat field spectrum root name
call clgstr ("flat_file", Memc[flat], SZ_FNAME)
# Apply coincidence corrections?
coincidence = clgetb ("coincor")
if (coincidence) {
ccmode = clgwrd ("ccmode", Memc[str], SZ_LINE, ",photo,iids,")
dtime = clgetr ("deadtime")
power = clgetr ("power")
}
# Initialize beam number status
call init_bs (Memi[bstat])
# Initialize range decoder
call reset_next_image ()
# Loop over all input images - divide and make new image.
# The output record number is incremented in all cases.
while (get_next_image (root, Memi[recs], nrecs, Memc[image],
SZ_FNAME) != EOF) {
start_rec = start_rec + 1
# Open image
iferr (im = immap (Memc[image], READ_ONLY, 0)) {
call erract (EA_WARN)
next
}
# Get header
iferr (qd_flag = imgeti (im, "QD-FLAG"))
qd_flag = -1
# Verify divide flag
if (qd_flag != 0) {
# Get flat field spectrum if needed
call get_flatsp (im, flatsp, Memc[flat], Memi[bstat], len_flat)
# Calibrate the current spectrum and make a calibrated version
call divide (im, flatsp, len_flat, Memc[image], Memc[ofile],
start_rec, coincidence, ccmode, dtime, power)
} else {
call eprintf ("[%s] already divided - ignored\n")
call pargstr (Memc[image])
}
}
# Update record number
call clputi ("next_rec", start_rec)
# Free space
call sfree (sp)
call clpcls (root)
end
# GET_FLATSP -- Load flat field spectrum for the current beam number
procedure get_flatsp (im, sp, flat_file, beam_stat, len_flat)
pointer im, sp
char flat_file[SZ_FNAME]
int beam_stat[ARB], len_flat
int i
int beam, len[MAX_NR_BEAMS]
char sfname[SZ_FNAME]
pointer flatsp[MAX_NR_BEAMS], imflat
int strlen(), imgeti()
pointer imgl1r(), immap()
errchk immap
begin
# Determine beam number.
iferr (beam = imgeti (im, "BEAM-NUM"))
beam = 0
beam = beam + 1
# Validate beam number
if (beam < 1 || beam > MAX_NR_BEAMS) {
call eprintf (" Beam number out of range: %d - using 0\n")
call pargi (beam)
beam = 1
}
# Has this beam already been loaded?
if (IS_INDEFI (beam_stat[beam])) {
# Create file name
call strcpy (flat_file, sfname, SZ_FNAME)
# Flat field file names have beam number appended
call sprintf (sfname[strlen(sfname)+1], SZ_FNAME, ".%04d")
call pargi (beam-1)
# Open spectrum
imflat = immap (sfname, READ_ONLY, 0)
# Allocate space for this beam's sensitivity spectrum
call salloc (flatsp[beam], IM_LEN(imflat,1), TY_REAL)
# Copy pixels into space
call amovr (Memr[imgl1r(imflat)], Memr[flatsp[beam]],
IM_LEN(imflat,1))
# Must be careful that no division by zero occurs.
do i = 1, IM_LEN(imflat,1) {
if (Memr[flatsp[beam]+i-1] == 0.0)
Memr[flatsp[beam]+i-1] = 1.0
}
# Mark this beam accounted for
beam_stat[beam] = 1
len[beam] = IM_LEN(imflat,1)
call imunmap (imflat)
}
# Point to the spectrum
sp = flatsp[beam]
len_flat = len[beam]
end
# DIVIDE -- Perform the division and create new spectrum
procedure divide (im, flat, len_flat, ifile, ofile, rec,
coincidence, ccmode, dtime, power)
pointer im, flat
int len_flat, rec, ccmode
real dtime, power
char ifile[ARB], ofile[ARB]
bool coincidence
real itm, imgetr()
int i, co_flag, imgeti()
int ncols, nlines
char calfname[SZ_FNAME], original[SZ_FNAME]
pointer imcal, rawpix, calpix
pointer immap(), impl2r(), imgl2r()
begin
# Find smallest length of the two possible spectra
ncols = min (IM_LEN (im, 1), len_flat)
# Create new spectrum. Make up a name
call sprintf (calfname, SZ_FNAME, "%s.%04d")
call pargstr (ofile)
call pargi (rec)
call xt_mkimtemp (ifile, calfname, original, SZ_FNAME)
imcal = immap (calfname, NEW_COPY, im)
IM_NDIM(imcal) = IM_NDIM(im)
IM_LEN (imcal,1) = ncols
IM_PIXTYPE(imcal) = TY_REAL
# Check for 2D spectrum
if (IM_NDIM(im) > 1)
nlines = IM_LEN(im,2)
else
nlines = 1
# Copy across the image title
call strcpy (IM_TITLE(im), IM_TITLE(imcal), SZ_LINE)
# Operate on the pixels
do i = 1, nlines {
rawpix = imgl2r (im,i)
calpix = impl2r (imcal,i)
# Apply coincidence correction if needed
co_flag = -1
if (coincidence) {
iferr (co_flag = imgeti (im, "CO-FLAG"))
;
if (co_flag < 1) {
iferr (itm = imgetr (im, "EXPOSURE"))
iferr (itm = imgetr (im, "ITIME"))
iferr (itm = imgetr (im, "EXPTIME"))
itm = 1.
call coincor (Memr[rawpix], Memr[rawpix], ncols,
itm, co_flag, dtime, power, ccmode)
}
}
call adivr (Memr[rawpix], Memr[flat], Memr[calpix], ncols)
}
call imaddi (imcal, "QD-FLAG", 0)
if (co_flag != -1)
call imaddi (imcal, "CO-FLAG", co_flag)
# Send user report
call printf ("writing [%s]: %s\n")
call pargstr (original)
call pargstr (IM_TITLE(imcal))
call flush (STDOUT)
call imunmap (im)
call imunmap (imcal)
call xt_delimtemp (calfname, original)
end
# INIT_BS -- Initialize beam status flags
procedure init_bs (beam_stat)
int beam_stat[ARB]
int i
begin
do i = 1, MAX_NR_BEAMS
beam_stat[i] = INDEFI
end
|