aboutsummaryrefslogtreecommitdiff
path: root/noao/imred/vtel/destreak.x
blob: 5002bab9303d8179cde96c7398a16b550e294e19 (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
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