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

root/DPWP/trunk/DPWP/adcp_matlab/radialtouvw.m

Revision 334 (checked in by gdusek, 14 years ago)

Total update to the DPWP code. Significant changes made to direspec, specmultiplot, radialtouvw and IMLM code. 6/14/10

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