aboutsummaryrefslogtreecommitdiff
path: root/noao/digiphot/daophot/addstar/dpartstar.x
blob: 9f464812cdf037ed32ca31394c61441050206281 (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
include <imhdr.h>
include <tbset.h>
include "../lib/daophotdef.h"
include "../lib/apseldef.h"

define	ADD_NINCOLUMN		4

# DP_ARTSTAR -- Add artificial stars to the data frames.

procedure dp_artstar (dao, iim, oim, cl, ofd, nstar, minmag, maxmag, iseed,
	coo_text, simple, offset, cache)

pointer	dao				# pointer to DAOPHOT structure
pointer	iim				# the input image descriptor
pointer	oim				# image to add stars to
int	cl				# fd of input photometry file
int	ofd				# fd of output photometry file
int	nstar				# number of stars to be added
real	minmag, maxmag			# min. and max. magnitudes to add
int	iseed[ARB]			# the random number generator array
bool	coo_text			# coordinate text file ?
int	simple				# simple text file ?
int	offset				# id offset for output photometry file
int	cache				# cache the output pixels

real	xmin, ymin, xwide, ywide, mwide, x, y, dxfrom_psf, dyfrom_psf, mag
real	radius, psfradsq, rel_bright, sky, tx, ty
pointer	sp, colpoint, psffit, subim, subim_new, indices, fields, key
int	i, iid, id, lowx, lowy, nxpix, nypix, nrow

pointer	dp_gsubrast(), imps2r(), tbpsta()
int	dp_gcoords(), dp_apsel()

begin
	# Get some memory.
	call smark (sp)
	call salloc (fields, SZ_LINE, TY_CHAR)
	call salloc (indices, ADD_NINCOLUMN, TY_INT)
	call salloc (colpoint, ADD_NINCOLUMN, TY_INT)

	# Initialize the input photometry file.
	key = NULL
	if (cl != NULL) {
	    if (! coo_text) {
		call dp_tadinit (cl, Memi[indices])
		nrow = tbpsta (cl, TBL_NROWS)
	    #} else if (coo_text && simple == NO) {
	    } else if (simple == NO) {
	        call pt_kyinit (key)
	        Memi[indices] = DP_PAPID
	        Memi[indices+1] = DP_PAPXCEN
	        Memi[indices+2] = DP_PAPYCEN
	        Memi[indices+3] = DP_PAPMAG1
	        call dp_gappsf (Memi[indices], Memc[fields], ADD_NINCOLUMN)
	    }
	}

	# Initialize the output table.
	if (DP_TEXT(dao) == YES)
	    call dp_xnaddstar (dao, ofd)
	else
	    call dp_tnaddstar (dao, ofd, Memi[colpoint])

	# Get some daophot pointers.
	psffit = DP_PSFFIT (dao)

	# Get the psf radius
	if (DP_PSFSIZE(psffit) == 0)
	    radius = DP_PSFRAD(dao)
	else
	    radius = min (DP_PSFRAD(dao), (real (DP_PSFSIZE(psffit) - 1) /
	        2.0 - 1.0) / 2.0)
	psfradsq = radius * radius

	# Get the x and y limits for the random number generator. The 
	# magnitude limits are input by the user.
	xmin = 1.0
	xwide = real(IM_LEN(oim,1)) - 1.0
	ymin = 1.0
	ywide = real (IM_LEN(oim,2)) - 1.0
	mwide = maxmag - minmag

	if (DP_VERBOSE (dao) == YES) {
	    call printf ("OUTPUT IMAGE: %s\n")
		call pargstr (IM_HDRFILE(oim))
	}

	# Add the stars.
	i = 1
	repeat {

	    # Get the coords and magnitudes of the star.
	    if (cl == NULL) {
	        call dp_mkcoords (x, y, mag, xmin, xwide, ymin, ywide, minmag,
		    mwide, iseed)
		id = i + offset
		if (i > nstar)
		    break
	    } else if (! coo_text) {
		if (i > nrow)
		    break
		call dp_tadread (cl, Memi[indices], iid, x, y, mag, i)
	        call dp_win (dao, iim, x, y, x, y, 1)
		if (iid == 0)
		    iid = i + offset
		else
		    id = iid
	    } else {
		if (simple == YES) {
	            if (dp_gcoords (cl, x, y, mag, iid) == EOF)
		        break
		    if (iid == 0)
			id = i + offset
		    else
			id = iid
		} else {
		    if (dp_apsel (key, cl, Memc[fields], Memi[indices], iid, x,
			y, sky, mag) == EOF) 
		        break
		    if (iid == 0)
			id = i + offset
		    else
			id = iid
		}
	        call dp_win (dao, iim, x, y, x, y, 1)
	    }

	    # Increment the counter
	    i = i + 1

	    # Compute the psf coordinates.
	    call dp_wpsf (dao, iim, x, y, dxfrom_psf, dyfrom_psf, 1)
	    dxfrom_psf = (dxfrom_psf - 1.0) / DP_PSFX(psffit) - 1.0
	    dyfrom_psf = (dyfrom_psf - 1.0) / DP_PSFY(psffit) - 1.0

	    # Compute output coordinates.
	    call dp_wout (dao, iim, x, y, tx, ty, 1)

	    # Read in the subraster and compute the relative x-y position.
	    subim = dp_gsubrast (oim, x, y, radius, lowx, lowy, nxpix, nypix)
	    if (subim == NULL) {
	       call printf (
	       "    Star: %d - X: %6.2f  Y: %6.2f  Mag: %7.3f off image\n")
		    call pargi (id)
		    call pargr (tx)
		    call pargr (ty)
		    call pargr (mag)
		next
	    } else if (DP_VERBOSE (dao) == YES) {
	       call printf (
	           "    Added Star: %d - X: %6.2f  Y: %6.2f  Mag: %7.3f\n")
		    call pargi (id)
		    call pargr (tx)
		    call pargr (ty)
		    call pargr (mag)
	    }

	    if (DP_TEXT(dao) == YES)
		call dp_xwadd (ofd, id, tx, ty, mag)
	    else
		call dp_twadd (ofd, Memi[colpoint], id, tx, ty, mag, id)

	    # Get the relative brightness
	    rel_bright = DAO_RELBRIGHT (psffit, mag)

	    # Get the output buffer.
	    subim_new = imps2r (oim, lowx, lowx + nxpix - 1, lowy,
	        lowy + nypix - 1)

	    # Evaluate the PSF for a single star.
	    x = x - lowx + 1.0
	    y = y - lowy + 1.0
	    call dp_artone (dao, Memr[subim], nxpix, nypix, x, y, rel_bright,
	        dxfrom_psf, dyfrom_psf, psfradsq, DP_PHOTADU(dao), iseed)

	    # Make sure the image buffer is flushed. Currently this is a
	    # very inefficient way to do the image i/o.
	    call amovr (Memr[subim], Memr[subim_new], nxpix * nypix)
	    if (cache == NO)
	        call imflush (oim)

	}

	# Release the text file structure.
	if (key != NULL)
	    call pt_kyfree (key)

	call sfree (sp)
end


# DP_ARTONE -- Add a single star to the image.

procedure dp_artone (dao, subin, nxpix, nypix, x, y, rel_bright, xfrom_psf,
	yfrom_psf, psfradsq, gain, iseed)

pointer	dao				# pointer to the daophot structure
real	subin[nxpix,nypix]		# input subraster
int	nxpix, nypix			# dimensions of subrasters
real	x, y				# input position
real	rel_bright			# relative brightness
real	xfrom_psf			# x distance from the psf
real	yfrom_psf			# y distance from the psf
real	psfradsq			# psf radius squared
real	gain				# gain
int	iseed[ARB]			# random number seed array

int	ix, iy
pointer	psffit
real	dx, dy, dxsq, dysq, radsq, dvdx, dvdy, value, err
real	dp_usepsf(), dp_nrml(), daoran()

begin
	psffit = DP_PSFFIT(dao)

	do iy = 1, nypix {
	    dy = real (iy) - y
	    dysq = dy * dy
	    do ix = 1, nxpix {
		dx = real (ix) - x
		dxsq = dx * dx
		radsq = dxsq + dysq
		if (radsq < psfradsq) {
		    value = rel_bright * dp_usepsf (DP_PSFUNCTION(psffit),
		        dx, dy, DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
			Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
			DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
			xfrom_psf, yfrom_psf, dvdx, dvdy)
		    err = daoran (iseed[mod(ix+iy,3)+1])
		    err = sqrt (max (0.0, value / gain)) * dp_nrml (err)
		    subin[ix,iy] = subin[ix,iy] + value + err
		}
	    }
	}
end


# DP_MKCOORDS -- Construct a list of coordinates using a random number
# generator.

procedure dp_mkcoords (x, y, mag, xmin, xwide, ymin, ywide, minmag, mwide,
	iseed)

real	x		# x array
real	y		# y array
real	mag		# magnitude array
real	xmin		# xmin value
real	xwide		# x coordinate range
real	ymin		# ymin value
real	ywide		# y coordinate range
real	minmag		# minimum magnitude
real	mwide		# the magnitude range
int	iseed[ARB]	# seed array for random number genrator

real	daoran()

begin
	x = xmin + daoran (iseed[1]) * xwide
	y = ymin + daoran (iseed[2]) * ywide
	mag = minmag + daoran (iseed[3]) * mwide
end


# DP_SEED3 -- Seed the random number generator.

procedure dp_seed3 (seed, iseed)

int	seed			# initial seed value
int	iseed[ARB]		# the seed array

int	idum
real	daoran()

begin
	idum = seed
	iseed[1] = int (524288.* daoran (idum)) + 1
	iseed[2] = int (524288.* daoran (idum)) + 1
	iseed[3] = int (524288.* daoran (idum)) + 1
end


# DP_NRML -- Convert a uniform probability distribution to a Gaussian
# distribution with mean zero and standard deviation of unity.

real procedure dp_nrml (random)

real 	random			# input random number 

real p, sign, t

begin
	p = random
	sign = -1.0
	if (p > 0.5) {
	    p = p - 0.5
	    sign = 1.0
	} else if (p <= 0.0)
	    return (-1.0e20)

	t = sqrt (log (1.0 / (p * p)))
	return (sign * (t - (2.30753 + 0.27061 * t) / 
	    (1.0 + t * (0.99229 + t * 0.04481))))
end