aboutsummaryrefslogtreecommitdiff
path: root/noao/imred/irred/t_irlincor.x
blob: 053c383d94959abacbb528c446fa231612a19083 (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
include <imhdr.h>
include	<error.h>

# Maximum number of correction function coefficients.
define	MAXCOEF	3

# Maximum number of ADU....
define	MAXADU	32767.0


# T_ARLINCOR -- Corrects IR imager frames for non linearity. This task
# only corrects a section of the total image and copies the rest of
# the image intact to the output image.

procedure t_irlincor ()

pointer	inlist, outlist		# input and output image lists
char	section[SZ_LINE]	# image section
pointer	coeff			# coeficients of correction function

bool	sflag
pointer	imin, imout
pointer	input, output, orig, temp
pointer	sp

int	strlen()
int	imtgetim(), imtlen()
real	clgetr()
pointer	immap(), imtopenp()

begin
	# Get parameters
	inlist  = imtopenp ("input")
	outlist = imtopenp ("output")
	call clgstr ("section", section, SZ_LINE)

	# Check that the input and output image lists have the
	# same number of images. Abort if that's not the case.
	if (imtlen (inlist) != imtlen (outlist)) {
	    call imtclose (inlist)
	    call imtclose (outlist)
	    call error (1, "Input and output image lists don't match")
	}

	# Set section flag
	sflag = (strlen (section) > 0)

	# Allocate string space
	call smark  (sp)
	call salloc (input,  SZ_FNAME, TY_CHAR)
	call salloc (output, SZ_FNAME, TY_CHAR)
	call salloc (orig,   SZ_FNAME, TY_CHAR)
	call salloc (temp,   SZ_FNAME, TY_CHAR)

	# Allocate memory for the correction coefficients and
	# read them from the parameter file.
	call malloc (coeff, MAXCOEF, TY_REAL)
	Memr[coeff]   = clgetr ("coeff1")
	Memr[coeff+1] = clgetr ("coeff2")
	Memr[coeff+2] = clgetr ("coeff3")

	# Loop over all images in the input and output lists
	while ((imtgetim (inlist, Memc[input], SZ_FNAME) != EOF) &&
	       (imtgetim (outlist, Memc[output], SZ_FNAME) != EOF)) {

	    # Generate temporary output image name to allow for
	    # input and output images having the same name
	    call xt_mkimtemp (Memc[input], Memc[output], Memc[orig], SZ_FNAME)

	    # Take different actions depending on whether the image section
	    # is specified or not, in order to optimize speed. When the image
	    # section is specified the input image is copied to the output
	    # image and then the output image opened to work on the section.
	    # Otherwise the output image is created only once.
	    if (sflag) {

	        # Copy input image into output image using fast copy
		iferr (call irl_imcopy (Memc[input], Memc[output])) {
		    call erract (EA_WARN)
		    next
		}

		# Append section to image names. The output name should
		# be preserved without the section for later use.
		call strcat (section, Memc[input], SZ_FNAME)
		call sprintf (Memc[temp], SZ_FNAME, "%s%s")
		    call pargstr (Memc[output])
		    call pargstr (section)

		# Open input and output images. The output image already
		# exists, since it was created by the copy operation, so
		# it is opened as read/write.
		iferr (imin = immap (Memc[input], READ_ONLY, 0)) {
		    call erract (EA_WARN)
		    next
		}
		iferr (imout = immap (Memc[temp], READ_WRITE, 0)) {
		    call imunmap (imin)
		    call erract (EA_WARN)
		    next
		}

	    } else {

		# Open input and output images. The output image does not
		# exist already so it is opened as a new copy of the input
		# image.
		iferr (imin = immap (Memc[input], READ_ONLY, 0)) {
		    call erract (EA_WARN)
		    next
		}
		iferr (imout = immap (Memc[output], NEW_COPY, imin)) {
		    call imunmap (imin)
		    call erract (EA_WARN)
		    next
		}

	    }

	    # Perform the linear correction.
	    call irl_correct (imin, imout, Memr[coeff], MAXCOEF)

	    # Close images
	    call imunmap (imin)
	    call imunmap (imout)

	    # Replace output image with the temporary image. This is a
	    # noop if the input and output images have different names
	    call xt_delimtemp (Memc[output], Memc[orig])
	}

	# Free memory and close image lists
	call mfree (coeff, TY_REAL)
	call imtclose (inlist)
	call imtclose (outlist)
end


# IRL_CORRECT -- Corrects an IR imager frame for non-linearity using a
# simple power series polynomial correction function:
#
# ADU' = ADU * [ a + b * (ADU / MAXADU) + c * (ADU / MAXADU) **2 ]
#

procedure irl_correct (imin, imout, coeff, ncoef)

pointer	imin				# input image pointer
pointer	imout				# output image pointer
real	coeff[ncoef]			# coefficients of polynomial function
int	ncoef				# number of polynomial coeficients

int	col, ncols
long	v1[IM_MAXDIM], v2[IM_MAXDIM]
pointer	inbuf, outbuf

int	imgeti()
int	imgnlr(), impnlr()
real	apolr()

begin
	# Initiliaze counters for line i/o
	call amovkl (long(1), v1, IM_MAXDIM)
	call amovkl (long(1), v2, IM_MAXDIM)

	# Number of pixels per line
	ncols = imgeti (imin, "i_naxis1")

	# Loop over image lines
	while ((imgnlr (imin, inbuf, v1) != EOF) &&
	       (impnlr (imout, outbuf, v2) != EOF)) {
	    call adivkr (Memr[inbuf], MAXADU, Memr[outbuf], ncols)
	    do col = 1, ncols {
		Memr[outbuf+col-1] = apolr (Memr[outbuf+col-1], coeff, ncoef)
	    }
	    call amulr (Memr[inbuf], Memr[outbuf], Memr[outbuf], ncols)
	}
end


# IRL_IMCOPY -- Copy input image into the output image. Avoid data type
# conversion in order to opetimize speed.

procedure irl_imcopy (input, output)

char	input[ARB]		# input image name
char	output[ARB]		# output image name

int	npix
long	vin[IM_MAXDIM], vout[IM_MAXDIM]
pointer	imin, imout
pointer	inline, outline

int	imgeti()
int	imgnls(), impnls()
int	imgnli(), impnli()
int	imgnll(), impnll()
int	imgnlr(), impnlr()
int	imgnld(), impnld()
int	imgnlx(), impnlx()
pointer	immap()

begin
	# Open input and output images
	iferr (imin = immap (input, READ_ONLY, 0))
	    call erract (EA_ERROR)
	iferr (imout = immap (output, NEW_COPY, imin)) {
	    call imunmap (imin)
	    call erract (EA_ERROR)
	}

	# Initiliaze counters
	call amovkl (long(1), vin,  IM_MAXDIM)
	call amovkl (long(1), vout, IM_MAXDIM)

	# Copy image lines
	switch (imgeti (imin, "i_pixtype")) {
	case TY_SHORT, TY_USHORT:
	    while (imgnls (imin, inline, vin) != EOF) {
		npix = impnls (imout, outline, vout)
		call amovs (Mems[inline], Mems[outline], npix)
	    }
	case TY_INT:
	    while (imgnli (imin, inline, vin) != EOF) {
		npix = impnli (imout, outline, vout)
		call amovi (Memi[inline], Memi[outline], npix)
	    }
	case TY_LONG:
	    while (imgnll (imin, inline, vin) != EOF) {
		npix = impnll (imout, outline, vout)
		call amovl (Meml[inline], Meml[outline], npix)
	    }
	case TY_REAL:
	    while (imgnlr (imin, inline, vin) != EOF) {
		npix = impnlr (imout, outline, vout)
		call amovr (Memr[inline], Memr[outline], npix)
	    }
	case TY_DOUBLE:
	    while (imgnld (imin, inline, vin) != EOF) {
		npix = impnld (imout, outline, vout)
		call amovd (Memd[inline], Memd[outline], npix)
	    }
	case TY_COMPLEX:
	    while (imgnlx (imin, inline, vin) != EOF) {
		npix = impnlx (imout, outline, vout)
		call amovx (Memx[inline], Memx[outline], npix)
	    }
	default:
	    call error (0, "Unsupported pixel type")
	}

	# Close images
	call imunmap (imin)
	call imunmap (imout)
end