aboutsummaryrefslogtreecommitdiff
path: root/sys/mwcs/iwsaxmap.x
blob: 47ad9f09b46f5663898c7b4444bd640a8d4b4645 (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
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<imhdr.h>
include	<imio.h>
include	"mwcs.h"

# IW_SETAXMAP -- If the reference image was opened with an image section,
# modify the Lterm to reflect the section transformation, and enable the
# axis map if any dimensional reduction was involved.

procedure iw_setaxmap (mw, im)

pointer	mw			#I pointer to MWCS descriptor
pointer	im			#I pointer to reference image

double	v
pointer	sp, ltv_1, ltv_2, ltm
int	wcsdim, ndim, physax, i, j
int	axno[MAX_DIM], axval[MAX_DIM]
int	o_axno[MAX_DIM], o_axval[MAX_DIM]
int	n_axno[MAX_DIM], n_axval[MAX_DIM]

begin
	# If there is no section we don't need to do anything.
	if (IM_SECTUSED(im) == NO)
	    return

	call smark (sp)

	ndim = IM_NPHYSDIM(im)
	call salloc (ltv_1, ndim, TY_DOUBLE)
	call salloc (ltv_2, ndim, TY_DOUBLE)
	call salloc (ltm, ndim*ndim, TY_DOUBLE)

	# The section transformation is  px = VSTEP * lx + VOFF, specifying
	# the transformation from logical to physical image coordinates.
	# The IMIO axis map is given by j=VMAP[i], mapping logical axis I to
	# physical axis J.  Hence the physical to logical transformation in
	# terms of IMIO units is given by  lx = (1/VSTEP) * px + (-VOFF/VSTEP).
	# Since the section transform forbids rotation the axes are independent.

	call aclrd (Memd[ltv_1], ndim)
	call aclrd (Memd[ltm], ndim * ndim)

	do i = 1, ndim {
	    if (IM_VSTEP(im,i) == 0)
		v = 1.0D0
	    else
		v = 1.0D0 / IM_VSTEP(im,i)

	    Memd[ltm+(i-1)*ndim+i-1] = v
	    Memd[ltv_2+(i-1)] = -(IM_VOFF(im,i) * v)
	}

	# Enter the section transformation.  This uses the axis map, but the
	# transformation is defined in terms of the physical image matrix,
	# which is defined by the old axis map before modification by the new
	# image section.  Hence we must do this step before editing the axis
	# map below.

	call mw_translated (mw, Memd[ltv_1], Memd[ltm], Memd[ltv_2], ndim)

	# Compute the axis map for the active image section relative to the
	# current physical image matrix.

	do j = 1, ndim {
	    for (i=1;  i <= IM_NDIM(im);  i=i+1)
		if (IM_VMAP(im,i) == j)
		    break
	    if (i > IM_NDIM(im)) {
		axno[j] = 0
		axval[j] = IM_VOFF(im,j)
	    } else {
		axno[j] = i
		axval[j] = 0
	    }
	}

	# Get the old axis map for the WCS.  In the general case the WCS can
	# have a dimension higher than the current image, i.e. if the current
	# image was produced by extracting a section of an image of higher
	# dimension.  In such a case the WCS will have an axis map relating
	# the physical axes of the current image back to the original physical
	# system.

	wcsdim = MI_NDIM(mw)
	call mw_gaxmap (mw, o_axno, o_axval, wcsdim)

	# Combine the old axis map and the axis map for the current image
	# section.  The old axis map physical->logical mapping maps WCS
	# physical axes to logical axes, which are the physical axes of the
	# current image.  The axis map for the current image section maps the
	# physical axes of the current image to the logical axes of the
	# section.  An axis removed in the WCS axis map is not visible in the
	# image axno/axval computed above; the corresponding axis in the
	# combined WCS axis map is unchanged.  The remaining axes are subject
	# to remapping by the mage axno/axval.  This mapping may set any of
	# the axes to a constant to further reduce the dimensionality of the
	# logical system, however that does not concern us here, we just pass
	# on the combined axno/axval vectors to mw_saxmap.

        do i = 1, wcsdim {
            if (o_axno[i] == 0) {
                n_axno[i] = 0
                n_axval[i] = o_axval[i]
            } else {
                physax = o_axno[i]
                n_axno[i] = axno[physax]
                n_axval[i] = axval[physax]
            }
	}

	# Set the new axis map.
	call mw_saxmap (mw, n_axno, n_axval, wcsdim)

	call sfree (sp)
end