aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/tmatch/tmatch.x
blob: 2d3ea22d7d1f5f0357d72a465f837db4afb3ae94 (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
include	<tbset.h>

#* HISTORY *
#* B.Simon	24-Aug-1994	original
# Phil Hodge	 8-Apr-1999	Call tbfpri.

# TMATCH -- Find closest matching rows between two tables

procedure tmatch ()

#--
pointer	input1		# First input table
pointer	input2		# Second input table
pointer	output		# Output table
pointer	match1		# Columns from first table used to match
pointer	match2		# Columns from second table used to match
double	maxnorm		# Maximum value of norm for allowed match
pointer	incol1		# Columns from first table copied to output
pointer	incol2		# Columns from second table copied to output
pointer	factor		# Multiplicative factors used in computing norm
pointer	diagfile	# Diagnostic output file
pointer	nmcol1		# Columns from first table in diagnostic output
pointer	nmcol2		# Columns from second table in diagnostic output
bool	sphere		# Apply spherical correction to first column?

bool	fold
int	mxcol1, mxcol2, ncol1, ncol2, nrow1, nrow2
int	phu_copied	# set by tbfpri and ignored
pointer	sp, in1, in2, col1, col2, index1, index2, weight, dist, closest

data	fold	/ false /

string	mismatch  "Both lists of match columns must have same length"
string	nomatch   "Match columns not found in table"

bool	clgetb()
double	clgetd()
int	tbpsta()
pointer	tbtopn()

begin
	# Allocate memory for strings

	call smark (sp)
	call salloc (input1, SZ_FNAME, TY_CHAR)
	call salloc (input2, SZ_FNAME, TY_CHAR)
	call salloc (output, SZ_FNAME, TY_CHAR)
	call salloc (match1, SZ_FNAME, TY_CHAR)
	call salloc (match2, SZ_FNAME, TY_CHAR)
	call salloc (incol1, SZ_FNAME, TY_CHAR)
	call salloc (incol2, SZ_FNAME, TY_CHAR)
	call salloc (factor, SZ_FNAME, TY_CHAR)
	call salloc (diagfile, SZ_FNAME, TY_CHAR)
	call salloc (nmcol1, SZ_FNAME, TY_CHAR)
	call salloc (nmcol2, SZ_FNAME, TY_CHAR)

	# Read task parameters

	call clgstr ("input1", Memc[input1], SZ_FNAME)
	call clgstr ("input2", Memc[input2], SZ_FNAME)
	call clgstr ("output", Memc[output], SZ_FNAME)
	call clgstr ("match1", Memc[match1], SZ_FNAME)
	call clgstr ("match2", Memc[match2], SZ_FNAME)
	maxnorm = clgetd ("maxnorm")

	call clgstr ("incol1", Memc[incol1], SZ_FNAME)
	call clgstr ("incol2", Memc[incol2], SZ_FNAME)
	call clgstr ("factor", Memc[factor], SZ_FNAME)
	call clgstr ("diagfile", Memc[diagfile], SZ_FNAME)
	call clgstr ("nmcol1", Memc[nmcol1], SZ_FNAME)
	call clgstr ("nmcol2", Memc[nmcol2], SZ_FNAME)
	sphere = clgetb ("sphere")

	# Open input tables and get list of match colums

	in1 = tbtopn (Memc[input1], READ_ONLY, NULL)
	in2 = tbtopn (Memc[input2], READ_ONLY, NULL)

	mxcol1 = tbpsta (in1, TBL_NCOLS)
	mxcol2 = tbpsta (in2, TBL_NCOLS)

	call salloc (col1, mxcol1, TY_INT)
	call salloc (col2, mxcol2, TY_INT)

	call tctexp (in1, Memc[match1], mxcol1, ncol1, Memi[col1])
	call tctexp (in2, Memc[match2], mxcol2, ncol2, Memi[col2])

	if (ncol1 != ncol2)
	    call error (1, mismatch)

	if (ncol1 == 0)
	    call error (1, nomatch)

	if (ncol1 < 2)
	    sphere = false

	# Sort input tables

	call allrows (in1, nrow1, index1)
	call allrows (in2, nrow2, index2)
	
	call tbtsrt (in1, ncol1, Memi[col1], fold, nrow1, Memi[index1])
	call tbtsrt (in2, ncol2, Memi[col2], fold, nrow2, Memi[index2])

	call salloc (weight, ncol1, TY_DOUBLE)
	call salloc (dist, nrow1, TY_DOUBLE)
	call salloc (closest, nrow1, TY_INT)

	# Compute weights from list of factors or table column units

	call getweight (ncol1, Memi[col1], Memi[col2], 
			Memc[factor], Memd[weight])

	# Compute closest match between the two tables

	call getmatch (in1, in2, ncol1, Memi[col1], Memi[col2], Memd[weight], 
		       nrow1, Memi[index1], nrow2, Memi[index2], maxnorm, 
		       sphere, Memi[closest], Memd[dist])

	# Write output table

	call tbfpri (Memc[input1], Memc[output], phu_copied)
	call putmatch (Memc[output], Memc[incol1], Memc[incol2], in1, in2, 
		       nrow1, Memi[closest])

	# Write diagnostic info

	call infomatch (Memc[diagfile], in1, in2, Memc[nmcol1], Memc[nmcol2], 
			maxnorm, nrow1, Memi[closest], Memd[dist])

	# Clean up

	call mfree (index1, TY_INT)
	call mfree (index2, TY_INT)
	call tbtclo (in1)
	call tbtclo (in2)
	call sfree (sp)
end