NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/DPWavesProc/trunk/DPWavesProc/adcp_matlab/radialtouvw.m

Revision 232 (checked in by gdusek, 15 years ago)

--

Line 
1 function [ID,SM,EP]=radialtouvw(pressure,range,orbit,sysinfo,data_type)
2
3
4 %This code takes the loaded orbit, pressure and system info data from an
5 %ADCP waves output and computes the uvw velocities in earth coordinates.
6 %It also interpolates to remove bad data points and prepares the data
7 %structure required for running the DIWASP program.  The output will be in
8 %the structures ID, SM and EP.
9
10 %data_type is:
11 %1 to use uvw and pressure to generate the data structures,
12 %2 to use ranges
13 %3 to use radial velocity data
14
15
16
17 %make sure to load: pressure=load('pressure data'),
18 %orbit=load('orbital data'),sysinfo=load('sysinfo data') and range
19
20 %what is the transducer face height off the bottom?
21 adcpheight=0.4;
22
23 %whats the magnetic variation
24 magvar=-10;
25
26 %set up sysinfo file
27 samplesInBurst=sysinfo(3,:);
28 binsOut=sysinfo(8,:);
29 bin1height=sysinfo(9,:);
30 bin2height=sysinfo(10,:);
31 bin3height=sysinfo(11,:);
32 bin4height=sysinfo(12,:);
33 bin5height=sysinfo(13,:);
34 heading=sysinfo(18,:);
35 pitch=sysinfo(19,:);
36 roll=sysinfo(20,:);
37
38
39 %set up pressure
40 press=pressure/1000;
41
42 %find the average depth
43 avgdepth=mean(press)+adcpheight;
44
45 %set up range
46 range=range/1000;
47 meanrange=mean(range);
48 meanrange=repmat(meanrange,samplesInBurst,1);
49 dmrange=range-meanrange;
50 std_range=std(dmrange);
51
52 % Take out any bad data points in orbital data
53 ibad=find(orbit < -32000);
54 orbit(ibad) = NaN;
55 orbit=orbit/1000;
56 orbitnew=orbit;
57
58 % calculate the total number of orbital bins output (usually 20)
59 orbOut=binsOut*4;
60
61 %interpolate to take out any NaNs and QC for bad data in orbital data
62 std_orbit=ones(1,orbOut);
63 for i=1:orbOut
64    
65     %first take out any points outside of 4 std deviations
66     std_orbit(i)=nanstd(orbit(:,i));
67     ibad_std=find(abs(orbit(:,i)) > 4*std_orbit(i));
68     orbit(ibad_std,i)=NaN;
69 end
70 %find the avg std deviation for each group 4 beams
71 for i=4:4:orbOut
72     avgstd_orbit(i-3:i)=mean(std_orbit(i-3:i));
73 end
74
75 %now remove the points outside 4avg std dev and interp
76 for i=1:orbOut
77     ibad_std=find(abs(orbit(:,i)) > 4*avgstd_orbit(i));
78     orbit(ibad_std,i)=NaN;
79    
80     time=[1:1:length(orbit(:,i))];
81     NaNs=isnan(orbit(:,i));
82     igood=find(NaNs == 0);
83     ibad=find(NaNs == 1);
84
85     intValues= interp1(time(igood),orbit(igood,i),time(ibad),'linear','extrap');
86     orbitnew(ibad,i)=intValues;   
87 end
88
89 % Do similar QC for the range data
90 rangenew=dmrange;
91 for i=1:4
92     ibad=find(abs(dmrange(:,i)) > 4*std_range(:,i));
93     dmrange(ibad,i)=NaN;
94     time=[1:1:length(range(:,i))];
95     NaNs=isnan(dmrange(:,i));
96     igood=find(NaNs == 0);
97     ibad=find(NaNs == 1);
98
99     intValues= interp1(time(igood),dmrange(igood,i),time(ibad),'linear','extrap');
100     rangenew(ibad,i)=intValues;
101 end
102
103 dmrange=rangenew;
104    
105 %change heading, pitch, roll into degrees
106      
107 heading = heading/100;
108 pitch=pitch/100;
109 roll=roll/100;
110 pitch_out=pitch;
111 roll_out=roll;
112
113 %When converting to earth coordinates, the directions will be wrong unless we
114 %correct for bottom/up facing ADCPs, simply by rotating the roll by 180   
115 roll=roll+180;
116
117 %Set up geometry for transformation from beam to instrument
118 C1 = 1;
119 A1 = 1/(2*sin(20*pi/180));
120 B1 = 1/(4*cos(20*pi/180));
121 D1 = A1/sqrt(2);
122
123 % coordinate transformation matrix
124 CH = cos((heading+magvar)*pi/180);
125 SH = sin((heading+magvar)*pi/180);
126 CP = cos((pitch)*pi/180);
127 SP = sin((pitch)*pi/180);
128 CR = cos((roll)*pi/180);
129 SR = sin((roll)*pi/180);
130
131 %  let the matrix elements be ( a b c; d e f; g h j);
132 a = CH.*CR + SH.*SP.*SR;  b = SH.*CP; c = CH.*SR - SH.*SP.*CR;
133 d = -SH.*CR + CH.*SP.*SR; e = CH.*CP; f = -SH.*SR - CH.*SP.*CR;
134 g = -CP.*SR;              h = SP;     j = CP.*CR;
135 uno=1;
136
137 %reshape the orbital matrix to 3 dimensions
138
139 radial=reshape(orbitnew,samplesInBurst,4,binsOut);
140    
141 %  Compute uvw velocities and change to earth coordinates
142  
143 u = C1*A1*(radial(:,1,:)-radial(:,2,:));
144 v = C1*A1*(radial(:,4,:)-radial(:,3,:));
145 w = B1*(radial(:,1,:)+radial(:,2,:)+radial(:,3,:)+radial(:,4,:));
146 error_vel = D1*(radial(:,1,:)+radial(:,2,:)-radial(:,3,:)-radial(:,4,:));
147    
148 u=reshape(u,samplesInBurst,binsOut);
149 v=reshape(v,samplesInBurst,binsOut);
150 w=reshape(w,samplesInBurst,binsOut);
151 error_vel=reshape(error_vel,samplesInBurst,binsOut);
152
153 [m,n] = size(u);
154 uno = ones(m,binsOut);
155 unew = u.*(uno*a) + v.*(uno*b) + w.*(uno*c);
156 vnew = u.*(uno*d) + v.*(uno*e) + w.*(uno*f);
157 wnew = u.*(uno*g) + v.*(uno*h) + w.*(uno*j);
158
159 u_all = unew;v_all=vnew;w_all=wnew;
160 error_vel_all = error_vel;
161
162 %compute the original x,y,z positions for each beam for each bin to be accurate we need to take out the adcpheight
163
164 xyzpos=ones(3,4,5);
165 heights=[bin1height bin2height bin3height bin4height bin5height avgdepth]-adcpheight;
166 pos=heights*tan(20*pi/180);
167 for i=1:5
168     xyzpos(:,1,i)=[pos(i),0,heights(i)];
169     xyzpos(:,2,i)=[-pos(i),0,heights(i)];
170     xyzpos(:,3,i)=[0,pos(i),heights(i)];
171     xyzpos(:,4,i)=[0,-pos(i),heights(i)];
172 end
173
174 % set up the new coordinate transformation matrix
175 CH = cos((heading+magvar)*pi/180);
176 SH = sin((heading+magvar)*pi/180);
177 CP = cos((pitch_out)*pi/180);
178 SP = sin((pitch_out)*pi/180);
179 CR = cos((-roll_out)*pi/180);
180 SR = sin((-roll_out)*pi/180);
181
182 %  let the matrix elements be ( a b c; d e f; g h j), a slightly different
183 %  matrix from before;
184 a = CH.*CR - SH.*SP.*SR;  b = SH.*CP; c = -CH.*SR - SH.*SP.*CR;
185 d = -SH.*CR - CH.*SP.*SR; e = CH.*CP; f = SH.*SR - CH.*SP.*CR;
186 g = CP.*SR;              h = SP;     j = CP.*CR;
187
188 %transform the original x,y,z positions to the new positions accounting for
189 %heading, pitch and roll... we also add adcpheight back in
190 new_xyzpos=ones(3,4,5);
191 new_xyzpos(1,:,:)=xyzpos(1,:,:)*a+xyzpos(2,:,:)*b+xyzpos(3,:,:)*c;
192 new_xyzpos(2,:,:)=xyzpos(1,:,:)*d+xyzpos(2,:,:)*e+xyzpos(3,:,:)*f;
193 new_xyzpos(3,:,:)=xyzpos(1,:,:)*g+xyzpos(2,:,:)*h+xyzpos(3,:,:)*j+adcpheight;
194
195 xyzpositions=new_xyzpos;
196
197
198 %now we need to figure out the xyz positions at the surface for the range
199 %sin45=0.7071
200
201 binheight=heights(:,6);
202    
203 %beam 3
204 bearing=(heading+magvar)*(pi/180);
205 distfromz=binheight*tan((20-pitch_out)*(pi/180));
206 xpos=sin(bearing)*distfromz;
207 ypos=cos(bearing)*distfromz;
208
209 distroll=binheight*tan(roll_out*(pi/180));
210 beam3xpos=xpos+0.7071*distroll;
211 beam3ypos=ypos+0.7071*distroll;
212    
213 %beam 4
214 bearing=bearing+pi;
215 distfromz=binheight*tan((20+pitch_out)*(pi/180));
216 xpos=sin(bearing)*distfromz;
217 ypos=cos(bearing)*distfromz;
218
219 distroll=binheight*tan(roll_out*(pi/180));
220 beam4xpos=xpos+0.7071*distroll;
221 beam4ypos=ypos+0.7071*distroll;
222
223 %beam 1
224 bearing=bearing-pi/2;
225 distfromz=binheight*tan((20+roll_out)*(pi/180));
226 xpos=sin(bearing)*distfromz;
227 ypos=cos(bearing)*distfromz;
228
229 distroll=binheight*tan(pitch_out*(pi/180));
230 beam1xpos=xpos+0.7071*distroll;
231 beam1ypos=ypos+0.7071*distroll;
232
233 %beam2
234 bearing=bearing+pi;
235 distfromz=binheight*tan((20-roll_out)*(pi/180));
236 xpos=sin(bearing)*distfromz;
237 ypos=cos(bearing)*distfromz;
238
239 distroll=binheight*tan(pitch_out*(pi/180));
240 beam2xpos=xpos+0.7071*distroll;
241 beam2ypos=ypos+0.7071*distroll;
242
243 xypositions(:,:)=[beam1xpos beam2xpos beam3xpos beam4xpos; beam1ypos beam2ypos beam3ypos beam4ypos];
244    
245 %Put into structures for DIWASP
246
247
248 %sampling frequency
249 ID.fs=2;
250 %depth
251 ID.depth=(adcpheight+mean(press));
252 %the spectral matrix structure
253 SM.freqs=[0.01:0.01:0.4];
254 SM.dirs=[0:2:360];
255 SM.xaxisdir= 90;
256 %the estimation parameter
257 EP.method= 'EMEP';
258 EP.iter=100;
259
260
261 if data_type == 1
262     %For uvw and pressure for bins 2,3,4
263     % the datatypes
264     ID.datatypes={'pres' 'velx' 'vely' 'velz' 'velx' 'vely' 'velz' 'velx' 'vely' 'velz'};
265     % the layout
266     ID.layout = [ 0 0 0 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0 0 0;
267     adcpheight bin2height bin2height bin2height bin3height bin3height bin3height bin4height bin4height bin4height];
268     % the data
269     ID.data = horzcat(press, u_all(:,2), v_all(:,2), w_all(:,2), u_all(:,3), v_all(:,3), w_all(:,3), u_all(:,4), v_all(:,4), w_all(:,4));
270    
271 elseif data_type == 2
272     %For the ranges of each beam
273     % the datatypes
274     ID.datatypes={'elev' 'elev' 'elev' 'elev'};
275     % the layout
276     ID.layout = [xypositions(1,1) xypositions(1,2) xypositions(1,3) xypositions(1,4);
277     xypositions(2,1) xypositions(2,2) xypositions(2,3) xypositions(2,4);
278     avgdepth avgdepth avgdepth avgdepth];
279     % the data
280     ID.data = horzcat(dmrange(:,1), dmrange(:,2), dmrange(:,3), dmrange(:,4));
281
282 elseif data_type == 3
283     % For the radial velocities bins 2,3,4
284     % the datatypes
285     ID.datatypes={'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial' 'radial'};
286     % the layout
287     ID.layout = [xyzpositions(1,1,2) xyzpositions(1,2,2) xyzpositions(1,3,2) xyzpositions(1,4,2) xyzpositions(1,1,3) xyzpositions(1,2,3) xyzpositions(1,3,3) xyzpositions(1,4,3) xyzpositions(1,1,4) xyzpositions(1,2,4) xyzpositions(1,3,4) xyzpositions(1,4,4);
288     xyzpositions(2,1,2) xyzpositions(2,2,2) xyzpositions(2,3,2) xyzpositions(2,4,2) xyzpositions(2,1,3) xyzpositions(2,2,3) xyzpositions(2,3,3) xyzpositions(2,4,3) xyzpositions(2,1,4) xyzpositions(2,2,4) xyzpositions(2,3,4) xyzpositions(2,4,4);
289     xyzpositions(3,1,2) xyzpositions(3,2,2) xyzpositions(3,3,2) xyzpositions(3,4,2) xyzpositions(3,1,3) xyzpositions(3,2,3) xyzpositions(3,3,3) xyzpositions(3,4,3) xyzpositions(3,1,4) xyzpositions(3,2,4) xyzpositions(3,3,4) xyzpositions(3,4,4)];
290     % the data
291     ID.data = horzcat(orbitnew(:,5),orbitnew(:,6),orbitnew(:,7),orbitnew(:,8),orbitnew(:,9),orbitnew(:,10),orbitnew(:,11),orbitnew(:,12),orbitnew(:,13),orbitnew(:,14),orbitnew(:,15),orbitnew(:,16));
292
293     % the layout using bins 3,4,5
294     %ID.layout = [xyzpositions(1,1,5) xyzpositions(1,2,5) xyzpositions(1,3,5) xyzpositions(1,4,5) xyzpositions(1,1,4) xyzpositions(1,2,4) xyzpositions(1,3,4) xyzpositions(1,4,4) xyzpositions(1,1,3) xyzpositions(1,2,3) xyzpositions(1,3,3) xyzpositions(1,4,3);
295    % xyzpositions(2,1,5) xyzpositions(2,2,5) xyzpositions(2,3,5) xyzpositions(2,4,5) xyzpositions(2,1,4) xyzpositions(2,2,4) xyzpositions(2,3,4) xyzpositions(2,4,4) xyzpositions(2,1,3) xyzpositions(2,2,3) xyzpositions(2,3,3) xyzpositions(2,4,3);
296    % xyzpositions(3,1,5) xyzpositions(3,2,5) xyzpositions(3,3,5) xyzpositions(3,4,5) xyzpositions(3,1,4) xyzpositions(3,2,4) xyzpositions(3,3,4) xyzpositions(3,4,4) xyzpositions(3,1,3) xyzpositions(3,2,3) xyzpositions(3,3,3) xyzpositions(3,4,3)];
297     % the data
298    % ID.data = horzcat(orbitnew(:,17),orbitnew(:,18),orbitnew(:,19),orbitnew(:,20),orbitnew(:,13),orbitnew(:,14),orbitnew(:,15),orbitnew(:,16),orbitnew(:,9),orbitnew(:,10),orbitnew(:,11),orbitnew(:,12));
299
300 end
301
302
303
304
305  
306
307
308
309
310
311
Note: See TracBrowser for help on using the browser.