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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
|
include <mach.h>
include <imhdr.h>
include <imset.h>
include "vt.h"
define WINDEXC 800. # constant for weight index calculation
define WINDEX6TH 75. # constant for weight index calculation
define LIMBR .97 # Limb closeness rejection coefficient.
define SOWTHRESH 20. # Sum of weights threshold.
define SZ_WT10830 1024 # size of weight table for destreak
define FCORRECT .9375 # fractional term for lattitude correction
# Structure for least square fitting parameters.
define VT_LENSQSTRUCT 8 # Length of VT sq structure
# Pointers
define VT_SQ1P Memi[$1] # pointers to arrays for least
define VT_SQ1Q1P Memi[$1+1] # squares fit
define VT_SQ1Q2P Memi[$1+2] #
define VT_SQ1Q3P Memi[$1+3] #
define VT_SQ2Q2P Memi[$1+4] #
define VT_SQ2Q3P Memi[$1+5] #
define VT_SQ3Q3P Memi[$1+6] #
define VT_NUMDATAP Memi[$1+7] #
# Macro definitions
define VT_SQ1 Memr[VT_SQ1P($1)+$2-1]
define VT_SQ1Q1 Memr[VT_SQ1Q1P($1)+$2-1]
define VT_SQ1Q2 Memr[VT_SQ1Q2P($1)+$2-1]
define VT_SQ1Q3 Memr[VT_SQ1Q3P($1)+$2-1]
define VT_SQ2Q2 Memr[VT_SQ2Q2P($1)+$2-1]
define VT_SQ2Q3 Memr[VT_SQ2Q3P($1)+$2-1]
define VT_SQ3Q3 Memr[VT_SQ3Q3P($1)+$2-1]
define VT_NUMDATA Memi[VT_NUMDATAP($1)+$2-1]
# DESTREAK -- Destreak 10830 grams. On a 10830 full disk image. For
# each diode, based on the data from that diode calculate coefficients for
# a best fit function and subtract this function from the data. Apply a
# spatial filter to the resulting image.
procedure t_destreak()
char heimage[SZ_FNAME] # input image
char heout[SZ_FNAME] # output image
char tempim[SZ_FNAME] # temporary image
bool verbose # verbose flag
real el[LEN_ELSTRUCT] # ellipse parameters data structure
int threshold # squibby brightness threshold
int diode, npix, i, line
int kxdim, kydim
real kernel[3,9]
pointer weights
pointer lgp1, lpp
pointer heim, heoutp
pointer a, c
pointer sqs, sp
bool clgetb()
int clgeti()
real imgetr()
pointer imgl2s(), impl2s(), immap()
errchk immap, imgl2s, impl2s, imfilt
begin
call smark (sp)
call salloc (sqs, VT_LENSQSTRUCT, TY_STRUCT)
call salloc (VT_SQ1P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ1Q1P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ1Q2P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ1Q3P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ2Q2P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ2Q3P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_SQ3Q3P(sqs), DIM_VTFD, TY_REAL)
call salloc (VT_NUMDATAP(sqs), DIM_VTFD, TY_INT)
call salloc (a, DIM_VTFD, TY_REAL)
call salloc (c, DIM_VTFD, TY_REAL)
call salloc (weights, SZ_WT10830, TY_REAL)
# Get parameters from the cl.
call clgstr ("heimage", heimage, SZ_FNAME)
call clgstr ("heout", heout, SZ_FNAME)
call clgstr ("tempim", tempim, SZ_FNAME)
verbose = clgetb ("verbose")
threshold = clgeti("threshold")
# Open the images
heim = immap (heimage, READ_WRITE, 0)
heoutp = immap (tempim, NEW_COPY, heim)
# Ellipse parameters.
E_XCENTER[el] = imgetr (heim, "E_XCEN")
E_YCENTER[el] = imgetr (heim, "E_YCEN")
E_XSEMIDIAMETER[el] = imgetr (heim, "E_XSMD")
E_YSEMIDIAMETER[el] = imgetr (heim, "E_XSMD")
# Generate the weight array.
do i = 1, SZ_WT10830
Memr[weights+i-1] = exp((real(i) - WINDEXC)/WINDEX6TH)
# Set the sq arrays and the a and c arrays to zero.
call aclrr (VT_SQ1(sqs,1), DIM_VTFD)
call aclrr (VT_SQ1Q1(sqs,1), DIM_VTFD)
call aclrr (VT_SQ1Q2(sqs,1), DIM_VTFD)
call aclrr (VT_SQ1Q3(sqs,1), DIM_VTFD)
call aclrr (VT_SQ2Q2(sqs,1), DIM_VTFD)
call aclrr (VT_SQ2Q3(sqs,1), DIM_VTFD)
call aclrr (VT_SQ3Q3(sqs,1), DIM_VTFD)
call aclri (VT_NUMDATA(sqs,1), DIM_VTFD)
call aclrr (Memr[a], DIM_VTFD)
call aclrr (Memr[c], DIM_VTFD)
# for all lines in the image {
# calculate which diode this line corresponds to
# get the line from the image
# sum the q's for this line
# }
npix = IM_LEN(heim,1)
do line = 1, DIM_VTFD {
diode = mod((line - 1), SWTH_HIGH) + 1
lgp1 = imgl2s (heim, line)
call qsumq (Mems[lgp1], npix, el, threshold, weights, LIMBR,
line, sqs)
}
# Fit the function to the data for each line.
do line = 1, DIM_VTFD {
call qfitdiode(sqs, line, npix, Memr[a+line-1], Memr[c+line-1],
threshold, verbose)
if (verbose) {
call printf ("line = %d\n")
call pargi (line)
call flush (STDOUT)
}
}
# For each image line subtract the function from the data.
do line = 1, DIM_VTFD {
diode = mod((line - 1), SWTH_HIGH) + 1
lgp1 = imgl2s (heim, line)
lpp = impl2s (heoutp, line)
call qrfunct(Mems[lgp1], Mems[lpp], npix, el, threshold,
Memr[a+line-1], Memr[c+line-1], LIMBR, line)
}
# Switch images
call imunmap (heim)
call imunmap (heoutp)
heim = immap (tempim, READ_WRITE, 0)
heoutp = immap (heout, NEW_COPY, heim)
# Call the spacial filter program.
# First we have to load up the filter kernel
kxdim = 3
kydim = 9
kernel[1,1] = .017857
kernel[1,2] = .017857
kernel[1,3] = .035714
kernel[1,4] = .035714
kernel[1,5] = .035714
kernel[1,6] = .035714
kernel[1,7] = .035714
kernel[1,8] = .017857
kernel[1,9] = .017857
kernel[2,1] = .017857
kernel[2,2] = .053571
kernel[2,3] = .071428
kernel[2,4] = .071428
kernel[2,5] = .071428
kernel[2,6] = .071428
kernel[2,7] = .071428
kernel[2,8] = .053571
kernel[2,9] = .017857
kernel[3,1] = .017857
kernel[3,2] = .017857
kernel[3,3] = .035714
kernel[3,4] = .035714
kernel[3,5] = .035714
kernel[3,6] = .035714
kernel[3,7] = .035714
kernel[3,8] = .017857
kernel[3,9] = .017857
if (verbose) {
call printf ("filtering\n")
call flush(STDOUT)
}
call imfilt(heim, heoutp, kernel, kxdim, kydim, el)
# Unmap the images.
call imunmap(heim)
call imunmap(heoutp)
call sfree (sp)
end
# QFITDIODE -- Calculate the coefficients of the best fit functions.
procedure qfitdiode (sqs, line, npix, a, c, threshold, verbose)
pointer sqs # q's structure
int line # line in image
int npix # number of pixels
real a, c # returned coeffs
int threshold # sqib threshold
bool verbose # verbose flag
int i, j
real zz[4,4], limbr
begin
# If the number of points is insufficient, skip.
if (VT_NUMDATA(sqs,line) < 50) {
a = 0.0
c = 0.0
return
}
# First set the out arrays equal to the in arrays, initialize limbr.
limbr = LIMBR
# Clear the z array.
do i = 1,4
do j = 1,4
zz[i,j] = 0.0
# Fill the z array.
zz[1,2] = VT_SQ1Q1(sqs,line)
zz[1,3] = VT_SQ1Q2(sqs,line)
zz[1,4] = VT_SQ1Q3(sqs,line)
zz[2,3] = VT_SQ2Q2(sqs,line)
zz[2,4] = VT_SQ2Q3(sqs,line)
zz[3,4] = VT_SQ3Q3(sqs,line)
# Do the fit if the sum of weights is sufficient.
if (VT_SQ1(sqs,line) > SOWTHRESH)
call lstsq(zz,4,VT_SQ1(sqs,line))
else {
zz[3,1] = 0.0
zz[3,2] = 0.0
}
# Coefficients are:
if (verbose) {
call printf ("a = %g, c = %g ")
call pargr(zz[3,1])
call pargr(zz[3,2])
call flush(STDOUT)
}
c = zz[3,1]
a = zz[3,2]
end
# SUMQ -- Sum up the values of the Qs for the least squares fit.
procedure qsumq (in, npix, el, threshold, weights, limbr, y, sqs)
short in[npix] # array to sum from
pointer weights # weights
real el[LEN_ELSTRUCT] # limb fit ellipse struct
real limbr # limb closeness rejection coefficient
int npix # numpix in im line
int threshold # sqib threshold
int y # line in image
pointer sqs # pointer to q's structure
real q1, q2, q3
int i, windex, itemp
real rsq, r4th, r6th, r8th
real x, xfr, yfr, data
short k
int and()
short shifts()
begin
k = -4
# First, calculate the y fractional radius squared.
yfr = (abs(real(y) - E_YCENTER[el]))**2 / (E_YSEMIDIAMETER[el]**2)
# Do this for all the pixels in this row.
do i = 1, npix {
# Calculate the x fractional radius squared.
x = real(i)
xfr = (abs(x - E_XCENTER[el]))**2 / E_XSEMIDIAMETER[el]**2
# If off the disk, skip.
if (xfr > 1.0) {
next
}
# Check to see if the brightness of this data point is above the
# threshold, if not, skip.
itemp = in[i]
if (and(itemp,17B) < threshold)
next
# Strip off the squibby brightness, if data too big skip.
data = real(shifts(in[i], k))
if (data > 100.)
next
# Calculate the radius squared. (fractional)
rsq = xfr + yfr
# Check to see if the data point is on the disk.
if (rsq > limbr)
next
r4th = rsq * rsq
r6th = rsq * r4th
r8th = r4th * r4th
# Calculate the weight index.
windex = WINDEXC + data + WINDEX6TH * r6th
if (windex < 1)
windex = 1
if (windex > SZ_WT10830)
windex = SZ_WT10830
# Calculate the Qs.
q1 = Memr[weights+windex-1]
q2 = q1 * r6th
q3 = q1 * data
VT_SQ1(sqs,y) = VT_SQ1(sqs,y) + q1
VT_SQ1Q1(sqs,y) = VT_SQ1Q1(sqs,y) + q1 * q1
VT_SQ1Q2(sqs,y) = VT_SQ1Q2(sqs,y) + q1 * q2
VT_SQ1Q3(sqs,y) = VT_SQ1Q3(sqs,y) + q1 * q3
VT_SQ2Q2(sqs,y) = VT_SQ2Q2(sqs,y) + q2 * q2
VT_SQ2Q3(sqs,y) = VT_SQ2Q3(sqs,y) + q2 * q3
VT_SQ3Q3(sqs,y) = VT_SQ3Q3(sqs,y) + q3 * q3
VT_NUMDATA(sqs,y) = VT_NUMDATA(sqs,y) + 1
}
end
# QRFUNCT -- Remove FUNCTion. Remove the calculated function from the data
# from a particular diode. Each data point is checked to see if it is on
# disk. If it is not then the input pixel is copied to the output array.
# if it is on the disk, the function defined by a and c is subtracted from
# the data point before it is copied to the output array.
procedure qrfunct (in, out, npix, el, threshold, a, c, limbr, y)
short in[npix] # inline without fit removed
short out[npix] # inline with fit removed
real el[LEN_ELSTRUCT] # ellipse parameter struct
real a, c # fit coefficients
real limbr # limb closeness coefficient
int y # line of image
int npix # number of pixels in this line
int threshold # sqib threshold
int i
short fvalue
short data
real x, xfr, yfr, rsq, y4th, y6th
short correction
short k, kk
short shifts()
begin
k = -4
kk = 4
# If a and c have zeros, skip.
if (abs(a) < EPSILONR && abs(c) < EPSILONR) {
do i = 1, npix {
out[i] = in[i] # leave original data.
}
return
}
# First, calculate the y fractional radius.
yfr = (abs(real(y) - E_YCENTER[el]))**2 / (E_YSEMIDIAMETER[el]**2)
# Calculate the correction.
y4th = yfr*yfr
y6th = y4th*yfr
correction = short(FCORRECT*(6.0*yfr + 8.0*y4th + 16.0*y6th))
# Do this for all the pixels in the row.
do i = 1, npix {
# Calculate the x fractional radius.
x = real(npix/2 - i + 1)
xfr = (abs(real(i) - E_XCENTER[el]))**2 / E_XSEMIDIAMETER[el]**2
# If off the disk, skip.
if (xfr > 1.0) {
out[i] = in[i] # leave original data
next
}
# Check to see if the brightness of this data point is above the
# threshold, if not, skip.
if (and(int(in[i]),17B) < threshold) {
out[i] = in[i] # leave original data
next
}
# Strip off the squibby brightness
data = shifts(in[i], k)
# Calculate the radius squared. (fractional)
rsq = xfr + yfr
# Check to see if the data point is on the disk.
if (rsq > 1.0) {
out[i] = in[i] # leave original data
next
}
# Calculate the function value. Subtract it from the data value.
fvalue = short(a * rsq**3 + c) # a * r**6 + c
data = data - fvalue + correction
# data + squib bright
out[i] = shifts(data, kk) + short(and(int(in[i]),17B))
}
end
|