aboutsummaryrefslogtreecommitdiff
path: root/noao/onedspec/t_scoords.x
blob: fe2dd0672bc0ae1ed3c42a93cb4dc5b7be415073 (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
include	<error.h>
include	<imhdr.h>

# T_SCOORDS -- Set sampled coordinates in spectra.
# This task is currently limited to 1D spectra.
# It reads a text file of spectral coordinates and sets the WCS.

procedure t_scoords ()

pointer	speclist	# List of spectrum image names
pointer	coordlist	# List of coordinate file names
pointer	label		# Coordinate axis label
pointer	units		# Coordinate axis units

int	n, fd, open(), fscan(), nscan()
int	imtopenp, imtlen(), imtgetim(), clpopnu(), fntlenb(), fntgfnb()
bool	verbose, clgetb()
pointer	sp, spec, coords, values, im, tmp, immap()

errchk	immap, open, scoords

begin
	call smark (sp)
	call salloc (spec, SZ_FNAME, TY_CHAR)
	call salloc (coords, SZ_FNAME, TY_CHAR)
	call salloc (label, SZ_FNAME, TY_CHAR)
	call salloc (units, SZ_FNAME, TY_CHAR)

	# Get task parameters.
	speclist = imtopenp ("images")
	coordlist = clpopnu ("coords")
	call clgstr ("label", Memc[label], SZ_FNAME)
	call clgstr ("units", Memc[units], SZ_FNAME)
	verbose = clgetb ("verbose")

	# Check for match between image and coordinate lists.
	if (fntlenb (coordlist) > 1 && fntlenb (coordlist) != imtlen (speclist))
	    call error (1, "Image and coordinate lists do not match")

	# Loop through spectrum list.
	while (imtgetim (speclist, Memc[spec], SZ_FNAME) != EOF) {
	    if (fntgfnb (coordlist, Memc[coords], SZ_FNAME) == EOF)
		;

	    iferr {
		im = NULL
		fd = NULL

		# Open the image.
		tmp = immap (Memc[spec], READ_WRITE, 0); im = tmp

		# Get the coordinate values.
		tmp = open (Memc[coords], READ_ONLY, TEXT_FILE); fd = tmp
		call salloc (values, IM_LEN(im,1)+1, TY_DOUBLE)
		n = 0
		while (fscan(fd) != EOF) {
		    call gargd (Memd[values+n])
		    if (nscan() == 1)
			n = n + 1
		    if (n > IM_LEN(im,1))
			break
		}
		if (n != IM_LEN(im,1))
		    call error (1, "Wrong number of coordinate values in file")

		# Create the WCS
		if (verbose) {
		    call printf ("SCOORDS: ")
		    call printf (
			"Setting coordinates for %s from coordinate file %s.\n")
			call pargstr (Memc[spec])
			call pargstr (Memc[coords])
		}
		call scoords (im, Memc[label], Memc[units], Memd[values])
	    } then
		call erract (EA_WARN)

	    # Close files.
	    if (im != NULL)
		call imunmap (im)
	    if (fd != NULL)
		call close (fd)
	}

	call imtclose (speclist)
	call fntclsb (coordlist)
	call sfree (sp)
end



# SCOORDS -- Make a multispec pixel array coordinate system.
# This is currently limited to 1D spectra.

procedure scoords (im, label, units, waves)

pointer	im		#I Imageio I/O pointer (must be 1D image)
char	label[ARB]	#I Axis label (e.g. "Wavelength")
char	units[ARB]	#I Axis units (e.g. "Angstroms")
double	waves[ARB]	#I Array of dispersion coordinates

int	i, n, fd, stropen()
double	dw
pointer	sp, coeffs, mw, mw_open()

int	axes[6]
data	axes/1, 2, 1, 0, 0, 0/

errchk	mw_open, mw_saveim, stropen

begin
	call smark (sp)

	if (IM_NDIM(im) != 1)
	    call error (1, "scoords: image must be one dimensional")

	# Initialize the MWCS.
	mw = mw_open (NULL, 2)
	call mw_newsystem (mw, "multispec", 2)
	call mw_swtype (mw, axes, 2, "multispec", "")
	if (label[1] != EOS)
	    call mw_swattrs (mw, 1, "label", label)
	if (units[1] != EOS)
	    call mw_swattrs (mw, 1, "units", label)
	call mw_saxmap (mw, axes[3], axes[4], 2)

	# Setup multispec coefficient string.
	n = IM_LEN(im,1)
	i = 20 * (n + 6)
	call salloc (coeffs, i, TY_CHAR)
	call aclrc (Memc[coeffs], i)
	fd = stropen (Memc[coeffs], i, NEW_FILE)

	# Set the common attribute parameters.
	dw = (waves[n] - waves[1]) / (n - 1)
	call fprintf (fd, "%d %d %d %g %g %d %g %g %g ")
	    call pargi (1)		# Aperture number
	    call pargi (1)		# Beam number
	    call pargi (2)		# Dispersion type (2=non-linear)
	    call pargd (waves[1])	# Starting coordinate
	    call pargd (dw)		# Average dispersion
	    call pargi (n)		# Number of pixels
	    call pargd (0D0)		# Redshift
	    call pargd (INDEFD)		# Aperture limit
	    call pargd (INDEFD)		# Aperture limit

	# Set the general non-linear function parameters.
	call fprintf (fd, "%g %g %d ")
	    call pargd (1D0)		# Function weight
	    call pargd (0D0)		# Zero point shift
	    call pargi (5)		# Function type (5=pixel array)

	# Set the pixel array function values.
	call fprintf (fd, "%d")
	    call pargi (n)		# Number of pixels
	do i = 1, n {
	    if (i > 2) {
		if ((waves[i]-waves[i-1]) * dw <= 0) {
		    call strclose (fd)
		    call mw_close (mw)
		    call sfree (sp)
		    call error (1, "Coordinates are not monotonic")
		}
	    }

	    call fprintf (fd, " %g")
		call pargd (waves[i])	# Coordinates
	}

	# Write the attribute.
	call strclose (fd)
	call mw_swattrs (mw, 2, "spec1", Memc[coeffs])

	# Store the WCS in the image header.
	call mw_saveim (mw, im)
	call mw_close (mw)

	call sfree (sp)
end