3 |
michaesp |
1 |
function out = get_index (vert,position,grid);
|
|
|
2 |
|
|
|
3 |
% General index calculation for data grid
|
|
|
4 |
% Usage: out = int_index(vert,coords,grid)
|
|
|
5 |
% Example: grid.xmin = -180;
|
|
|
6 |
% grid.dx = 1;
|
|
|
7 |
% grid.nx = 361;
|
|
|
8 |
% grid.ymin = 0;
|
|
|
9 |
% grid.dy = 1;
|
|
|
10 |
% grid.ny = 91;
|
|
|
11 |
% out get_index(inp.P.data,[ 500 45 78; 250 56.7 78.4],grid)
|
|
|
12 |
|
|
|
13 |
% Get the position arrays
|
|
|
14 |
xpos = position(:,3)';
|
|
|
15 |
ypos = position(:,2)';
|
|
|
16 |
zpos = position(:,1)';
|
|
|
17 |
|
|
|
18 |
% Get the grid dimension
|
|
|
19 |
nx = size(vert,3);
|
|
|
20 |
ny = size(vert,2);
|
|
|
21 |
nz = size(vert,1);
|
|
|
22 |
|
|
|
23 |
% Get the horiozontal grid indices
|
|
|
24 |
rindx = (xpos-grid.xmin)/grid.dx+1;
|
|
|
25 |
rindy = (ypos-grid.ymin)/grid.dy+1;
|
|
|
26 |
|
|
|
27 |
% Special treatment if the the <vert> field is two-dimensional
|
|
|
28 |
if ( nz == 1 )
|
|
|
29 |
out = [ ones(size(rindy))', rindy', rindx' ];
|
|
|
30 |
return;
|
|
|
31 |
end
|
|
|
32 |
|
|
|
33 |
% Direction of the vertical axis (Pressure: descencding, Height: ascending)
|
|
|
34 |
dir = vert(2:nz,:,:) - vert(1:nz-1,:,:);
|
|
|
35 |
if ( mean(dir(:)) > 0 )
|
|
|
36 |
zpos = -zpos;
|
|
|
37 |
vert = -vert;
|
|
|
38 |
end
|
|
|
39 |
|
|
|
40 |
% Get the weights for the individual grid points
|
|
|
41 |
fracx = 1-rindx+floor(rindx);
|
|
|
42 |
fracy = 1-rindy+floor(rindy);
|
|
|
43 |
|
|
|
44 |
% Combine the indices i and j to a common index ij
|
|
|
45 |
vert1 = reshape(vert,nz,nx*ny);
|
|
|
46 |
|
|
|
47 |
% The position array and the vertical index is needed in the same format
|
|
|
48 |
zpos1 = kron(ones(nz,1),zpos);
|
|
|
49 |
zind1 = kron([1:nz]',ones(size(zpos)));
|
|
|
50 |
shif1 = (0:length(zpos)-1) * nz;
|
|
|
51 |
|
|
|
52 |
% Get the vertical indices at position 00
|
|
|
53 |
indx = floor(rindx);
|
|
|
54 |
indy = floor(rindy);
|
|
|
55 |
indxy = indy+(indx-1)*ny;
|
|
|
56 |
isnok1 = (indx<1) | (indx>nx) | (indy<1) | (indy>ny);
|
|
|
57 |
indxy(isnok1) = 1;
|
|
|
58 |
vert = vert1(:,indxy);
|
|
|
59 |
indz = max((vert>=zpos1).*zind1);
|
|
|
60 |
isnok2 = (indz<1) | (indz>=nz);
|
|
|
61 |
indz(isnok2) = 1;
|
|
|
62 |
indu = indz + shif1;
|
|
|
63 |
indo = indz + 1 + shif1;
|
|
|
64 |
diff = vert(indo)-vert(indu);
|
|
|
65 |
isnok3 = (diff==0);
|
|
|
66 |
diff(isnok3) = 1;
|
|
|
67 |
rind00 = indz + (zpos-vert(indu)) ./ diff;
|
|
|
68 |
isnok4 = isnok1 | isnok2 | isnok3;
|
|
|
69 |
rind00(isnok4) = NaN;
|
|
|
70 |
|
|
|
71 |
% Get the vertical indices at positions 01, 10, 11 (if necessary)
|
|
|
72 |
if ( any(fracx ~= 1) | any(fracy ~=1) )
|
|
|
73 |
|
|
|
74 |
indx = floor(rindx+1);
|
|
|
75 |
indy = floor(rindy);
|
|
|
76 |
indxy = indy+(indx-1)*ny;
|
|
|
77 |
isnok1 = (indx<1) | (indx>nx) | (indy<1) | (indy>ny);
|
|
|
78 |
indxy(isnok1) = 1;
|
|
|
79 |
vert = vert1(:,indxy);
|
|
|
80 |
indz = max((vert>zpos1).*zind1);
|
|
|
81 |
isnok2 = (indz<1) | (indz>=nz);
|
|
|
82 |
indz(isnok2) = 1;
|
|
|
83 |
indu = indz + shif1;
|
|
|
84 |
indo = indz + 1 + shif1;
|
|
|
85 |
diff = vert(indo)-vert(indu);
|
|
|
86 |
isnok3 = (diff==0);
|
|
|
87 |
diff(isnok3) = 1;
|
|
|
88 |
rind01 = indz + (zpos-vert(indu)) ./ diff;
|
|
|
89 |
isnok4 = isnok1 | isnok2 | isnok3;
|
|
|
90 |
rind01(isnok4) = NaN;
|
|
|
91 |
|
|
|
92 |
indx = floor(rindx);
|
|
|
93 |
indy = floor(rindy+1);
|
|
|
94 |
indxy = indy+(indx-1)*ny;
|
|
|
95 |
isnok1 = (indx<1) | (indx>nx) | (indy<1) | (indy>ny);
|
|
|
96 |
indxy(isnok1) = 1;
|
|
|
97 |
vert = vert1(:,indxy);
|
|
|
98 |
indz = max((vert>zpos1).*zind1);
|
|
|
99 |
isnok2 = (indz<1) | (indz>=nz);
|
|
|
100 |
indz(isnok2) = 1;
|
|
|
101 |
indu = indz + shif1;
|
|
|
102 |
indo = indz + 1 + shif1;
|
|
|
103 |
diff = vert(indo)-vert(indu);
|
|
|
104 |
isnok3 = (diff==0);
|
|
|
105 |
diff(isnok3) = 1;
|
|
|
106 |
rind10 = indz + (zpos-vert(indu)) ./ diff;
|
|
|
107 |
isnok4 = isnok1 | isnok2 | isnok3;
|
|
|
108 |
rind10(isnok4) = NaN;
|
|
|
109 |
|
|
|
110 |
indx = floor(rindx+1);
|
|
|
111 |
indy = floor(rindy+1);
|
|
|
112 |
indxy = indy+(indx-1)*ny;
|
|
|
113 |
isnok1 = (indx<1) | (indx>nx) | (indy<1) | (indy>ny);
|
|
|
114 |
indxy(isnok1) = 1;
|
|
|
115 |
vert = vert1(:,indxy);
|
|
|
116 |
indz = max((vert>zpos1).*zind1);
|
|
|
117 |
isnok2 = (indz<1) | (indz>=nz);
|
|
|
118 |
indz(isnok2) = 1;
|
|
|
119 |
indu = indz + shif1;
|
|
|
120 |
indo = indz + 1 + shif1;
|
|
|
121 |
diff = vert(indo)-vert(indu);
|
|
|
122 |
isnok3 = (diff==0);
|
|
|
123 |
diff(isnok3) = 1;
|
|
|
124 |
rind11 = indz + (zpos-vert(indu)) ./ diff;
|
|
|
125 |
isnok4 = isnok1 | isnok2 | isnok3;
|
|
|
126 |
rind11(isnok4) = NaN;
|
|
|
127 |
|
|
|
128 |
else
|
|
|
129 |
|
|
|
130 |
rind01 = rind00;
|
|
|
131 |
rind10 = rind00;
|
|
|
132 |
rind11 = rind00;
|
|
|
133 |
|
|
|
134 |
end
|
|
|
135 |
|
|
|
136 |
% Vectorised interpolation
|
|
|
137 |
rindz = fracx .* fracy .* rind00 + ...
|
|
|
138 |
(1-fracx) .* fracy .* rind01 + ...
|
|
|
139 |
fracx .* (1-fracy) .* rind10 + ...
|
|
|
140 |
(1-fracx) .* (1-fracy) .* rind11;
|
|
|
141 |
|
|
|
142 |
% Set the output of the function
|
|
|
143 |
nok = isnan(rindz') | isnan(rindy') | isnan(rindx');
|
|
|
144 |
out = [ rindz', rindy', rindx' ];
|
|
|
145 |
|
|
|
146 |
|
|
|
147 |
|