aboutsummaryrefslogtreecommitdiff
path: root/noao/nproto/t_binpairs.x
blob: 2efe380d527c21b2ee5af4ecc605955b43f6355c (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
define	MAXNBINS 100			# Maximum number of bins
define	MAXNPTS	10000			# Maximum number of data points


# T_BIN_PAIRS -- Bin pairs in separation
#
# The data points in two files, given as (x,y) values, are binned as a
# function of log separation.  The number of bins and the separation range
# are specified.  A list of separation, number of pairs in the bin,
# the number of pairs normalized by the total number of input pairs, and 
# the area of the bin are output.

procedure t_binpairs ()

char	file1[SZ_FNAME]			# Data file1
char	file2[SZ_FNAME]			# Data file2
real	rmin				# Minimum separation
real	rmax				# Maximum separation
int	nbins				# Number of separation bins
bool	verbose				# Verbose output

real	x1[MAXNPTS], y1[MAXNPTS]	# Data coordinates
real	x2[MAXNPTS], y2[MAXNPTS]	# Data coordinates
int	npts1, npts2			# Number of data points
int	npairs[MAXNBINS]		# Number of pairs

int	fd, i, nall
real	r1, r2

bool	clgetb(), strne()
real	clgetr()
int	clgeti(), open(), get_data()

begin
	# Get the pairs from file1.
	call clgstr ("file1", file1, SZ_FNAME)
	fd = open (file1, READ_ONLY, TEXT_FILE)
	npts1 = get_data (fd, x1, y1, MAXNPTS)
	call close (fd)

	# Get the pairs from file2 if different from file1.
	call clgstr ("file2", file2, SZ_FNAME)
	if (strne (file1, file2)) {
	    fd = open (file2, READ_ONLY, TEXT_FILE)
	    npts2 = get_data (fd, x2, y2, MAXNPTS)
	    call close (fd)
	} else
	    npts2 = 0

	# Get the separation bin parameters.
	rmin = clgetr ("rmin")
	rmax = clgetr ("rmax")
	nbins = min (clgeti ("nbins"), MAXNBINS)
	verbose = clgetb ("verbose")

	# Compute the pairs.
	call setbins (rmin, rmax, nbins)
	call bin_pairs (x1, y1, npts1, x2, y2, npts2, npairs, nbins, verbose)
	if (npts2 == 0)
	    nall = npts1 * (npts1 - 1)
	else
	    nall = npts1 * npts2

	# Print the results.
	call binr (1, r1)
	do i = 1, nbins {
	    call binr (i + 1, r2)
	    call printf ("%g %d %g %g\n")
		call pargr (r1)
		call pargi (npairs[i])
		call pargr (real (npairs[i]) / nall)
		call pargr (3.14159 * (r2 ** 2 - r1 ** 2))
	    r1 = r2
	}
end


# GET_DATA -- Get a list of x,y coordinates from a file and return the number
# of points.

int procedure get_data (fd, x, y, maxnpts)

int	fd			# Input file descriptor
real	x[maxnpts]		# X data coordinate
real	y[maxnpts]		# Y data coordinate
int	maxnpts			# Maximum number of data points to get
int	npts			# Return number of points

int	fscan(), nscan()

begin
	# Read the data
	npts = 0
	while (npts < MAXNPTS) {
	    if (fscan (fd) == EOF)
		break
	    npts = npts + 1
	    call gargr (x[npts])
	    call gargr (y[npts])
	    if (nscan() != 2)
		npts = npts - 1
	}
	return (npts)
end


# BIN_PAIRS -- Bin pairs in the input vectors.
#
# The points in the input vector(s) are binned according to the
# binnum procedure.  If npts2 is zero then the first vector is paired
# against itself (autocorrelation).

procedure bin_pairs (x1, y1, npts1, x2, y2, npts2, npairs, nbins, verbose)

real	x1[npts1], y1[npts1]		# Coordinates of points
int	npts1				# Number of points
real	x2[npts2], y2[npts2]		# Coordinates of points
int	npts2				# Number of points
int	npairs[nbins]			# Number of pairs
int	nbins				# Number of separation bins
bool	verbose				# Verbose output

int	i, j, k, bin

begin
	# Initialize bins
	do bin = 1, nbins
	    npairs[bin] = 0

	# Set printing interval
	if (verbose)
	    k = max (1, npts1 / 20)

	# Loop through all pairs of points
	do i = 1, npts1 {

	    # If npts2 is zero then pair the points in the first vector
	    # otherwise pair the points between the two vectors.

	    if (npts2 == 0) {
	        do j = i + 1, npts1 {
		    call binnum (x1[i], y1[i], x1[j], y1[j], bin)
		    if (bin > 0)
		        npairs[bin] = npairs[bin] + 2
	        }
	    } else {
	        do j = 1, npts2 {
		    call binnum (x1[i], y1[i], x2[j], y2[j], bin)
		    if (bin > 0)
		        npairs[bin] = npairs[bin] + 1
	        }
	    }

	    if (verbose) {
		if (mod (i, k) == 0) {
		    call eprintf ("%5.1f%%...\n")
		        call pargr (100. * i / npts1)
		}
	    }
	}
end


define  R2BINS		100	# Maximum number of r2 bins
define	HASHBINS	1000	# Size of r2 hash table

# SETBINS -- Set the mapping between separation and bin
# BINNUM  -- Return bin number for the given data points
# BINR    -- Return separation for the given bin

procedure setbins (rmin, rmax, nr)

real	rmin				# Minimum separation
real	rmax				# Maximum separation
int	nr				# Number of separation bins

real	x1, y1				# Data coordinate
real	x2, y2				# Data coordinate
int	bin				# Correlation Bin
real	r				# Separation

real	r2bins[R2BINS]			# r2 bins
int	hash[HASHBINS]			# Hash table

int	i, j, nbins
real	r2, dr2, r2zero
real	logr2, dlogr2, logr2zero

begin
	r2 = rmin ** 2
	dr2 = (rmax ** 2 - r2) / HASHBINS
	r2zero = 1 - r2 / dr2

	logr2 = 2 * log10 (rmin)
	dlogr2 = (2 * log10 (rmax) - logr2) / nr
	logr2zero = 1 - logr2 / dlogr2

	do i = 1, HASHBINS {
	    hash[i] = log10 (r2) / dlogr2 + logr2zero    
	    r2 = r2 + dr2
	}

	nbins = nr + 1
	do i = 1, nbins {
	    r2bins[i] = 10 ** logr2
	    logr2 = logr2 + dlogr2
	}

	return

entry binnum (x1, y1, x2, y2, bin)

	r2 = (x1 - x2) ** 2 + (y1 - y2) ** 2
	i = r2 / dr2 + r2zero

	if ((i < 1) || (i > HASHBINS))
	    bin = 0

	else {
	    j = hash[i]
	    do i = j + 1, nbins {
	        if (r2 < r2bins[i]) {
		    bin = i - 1
		    return
		}
	    }
	}

	return

entry binr (bin, r)

	r = sqrt (r2bins[bin])
end