This is a static copy of a profile reportHome
flagRFI_std (1 call, 5.891 sec)
Generated 05-Aug-2011 13:00:39 using cpu time.
function in file /home/LeechJ/cbass_analysis/reduc/flagRFI_std.m
Copy to new window for comparing multiple runs
Parents (calling functions)
Function Name | Function Type | Calls |
rfiWrapper | function | 1 |
Lines where the most time was spent
Line Number | Code | Calls | Total Time | % Time | Time Plot |
250 | runningMedLong = ... | 6 | 1.093 s | 18.6% |  |
294 | dataStdVec2_B(:,k) = ... | 6 | 1.082 s | 18.4% |  |
289 | dataStdVec2_A(:,k) = ... | 6 | 0.754 s | 12.8% |  |
203 | runningMed_A = ... | 6 | 0.459 s | 7.8% |  |
148 | dataStdVec_A = std(reshape(dat... | 6 | 0.426 s | 7.2% |  |
All other lines | | | 2.077 s | 35.3% |  |
Totals | | | 5.891 s | 100% | |
Children (called functions)
Code Analyzer results
Line number | Message |
419 | The value assigned to variable 'dataStdI2_A' might be unused. |
Coverage results
[ Show coverage for parent directory ]
Total lines in function | 530 |
Non-code lines (comments, blank lines) | 410 |
Code lines (lines that can run) | 120 |
Code lines that did run | 109 |
Code lines that did not run | 11 |
Coverage (did run/can run) | 90.83 % |
Function listing
time calls line
1 function flag = flagRFI_std(d,preFlag,params)
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % function [flagShort flagLong] = flagRFI_std(d,preFlag,params)
4 %
5 % Dec 20, 2010 (MAS) - Time series RFI flagging for C-BASS data. This is
6 % a two step process. First, data are flagged based upon sub-second RMS
7 % values from the polarization channels. Next, flagging is performed on
8 % 10s RMS values from the polarization channels. These flagging steps
9 % largely overlap, but do catch some different types.
10 %
11 % March 2, 2011 (MAS) - Converted to eval version; allows evaluation of
12 % flag values.
13 %
14 % March 11, 2011 (MAS) - Ignores those regions flagged by position.
15 %
16 % March 23, 2011 (MAS) - Trial final version; using strategy tested on
17 % late October 2010 data.
18 %
19 % April 14, 2011 (MAS) - Trial final version; comparison between I1 and
20 % I2 on long scales.
21 %
22 % params(1): minimum shortflag 1
23 % params(2): minimum shortflag 2
24 % params(3): shortflag slope
25 % params(4): minimum shortflag (alt)
26 % params(5): minimum longflag 1 A
27 % params(6): minimum longflag 1 B
28 % params(7): minimum longflag 2
29 % params(8): minimum I longflag
30 % params(9): minimum I difference.
31 % params(10): final smoothing (seconds)
32 % params(11): How much to smooth out the I long.
33 %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
36
37 %%%%%%%%%%%%%%
38 % Parameters:
39 %%%%%%%%%%%%%%
40
41 % Number of iterations in 0.5s flagging.
1 42 nClip = 5;
43
44 % Two lengths of sub-vectors in first flagging. 50 is 0.5s.
1 45 subLength_A = 25;
1 46 subLength_B = 2 * subLength_A;
47 % Smoothing length. Units of subLength. ie, 500 corresponds to 250s.
1 48 subStdLength = 250; % 100
49
50 % Two lengths of sub-vectors in second flagging. 1000 is 10s.
1 51 subLength2_A = 250;
1 52 subLength2_B = 4 * subLength2_A;
53
54
55
56
57 %%%%%%%%%%%%%%%%%%%%%%%%%%
58 % Begin the calculations!
59 %%%%%%%%%%%%%%%%%%%%%%%%%%
60
61 % Make the noise diode events look like non-noise diode events.
0.14 1 62 d = noiseRemove(d);
63
64
65
66 % Get the data matrix:
1 67 data = d.antenna0.receiver.data;
68
69 % Get its length.
1 70 dLength = length(data);
71
72
73 % The length of the first StdDev vector.
1 74 nSub_B = dLength / subLength_B;
1 75 nSubR_B = floor(nSub_B);
1 76 nSubR_A = nSubR_B * subLength_B / subLength_A;
77
78 % The length of the 10s StdDev vector.
1 79 nSub2_B = dLength / subLength2_B;
1 80 nSubR2_B = floor(nSub2_B);
1 81 nSubR2_A = nSubR2_B * subLength2_B / subLength2_A;
82
83
84
85 % Now we begin the first flagging.
86 %%%%%%%%%%%%%%%%%%%%%
87
88
89 % There's going to be some smoothing done on the standard deviation vector.
90 % We should prepare by calculating some length and padding parameters.
1 91 sLength_A = 2 ^ ceil(log2(nSubR_A + 2 * 10 * subStdLength));
1 92 sBuffStart_A = floor((sLength_A - nSubR_A) / 2);
1 93 sBuffEnd_A = ceil((sLength_A - nSubR_A) / 2);
94
1 95 sLength_B = 2 ^ ceil(log2(nSubR_B + 2 * 10 * subStdLength));
1 96 sBuffStart_B = floor((sLength_B - nSubR_B) / 2);
1 97 sBuffEnd_B = ceil((sLength_B - nSubR_B) / 2);
98
99
100 % Also, let's make the kernel for the convolution.
1 101 xKernel_A = (1:sLength_A)' - 1;
1 102 gaussKernelStd_A = ...
103 (exp(-0.5*(xKernel_A / subStdLength).^2) + ...
104 exp(-0.5*((sLength_A - xKernel_A) / subStdLength).^2)) / ...
105 (subStdLength*sqrt(2*pi));
106
1 107 xKernel_B = (1:sLength_B)' - 1;
0.01 1 108 gaussKernelStd_B = ...
109 (exp(-0.5*(xKernel_B / subStdLength).^2) + ...
110 exp(-0.5*((sLength_B - xKernel_B) / subStdLength).^2)) / ...
111 (subStdLength*sqrt(2*pi));
112
113 % Also, an X array which will later be used for interpolation purposes.
1 114 xStd_A = (1:nSubR_A);
1 115 xStd_B = (1:nSubR_B);
116
117
118
119 % Prep the resulting arrays from this endeavor.
1 120 dataStdNorm_A = zeros(nSubR_A,6);
1 121 dataStdNorm_B = zeros(nSubR_B,6);
122
1 123 dataStdVec2_A = zeros(nSubR2_A,6);
1 124 dataStdVec2_B = zeros(nSubR2_B,6);
125
126
127 % This will only proceed with a subvector of the data, determined by
128 % fitting in an integral number of subLength_B.
1 129 dataRStart = floor((dLength - nSubR_B * subLength_B) / 2) + 1;
1 130 dataREnd = dataRStart + nSubR_B * subLength_B - 1;
131
1 132 dataR2Start = floor((dLength - nSubR2_B * subLength2_B) / 2) + 1;
1 133 dataR2End = dataR2Start + nSubR2_B * subLength2_B - 1;
134
135
136 % Prep the positional flags.
1 137 preFlagR = max(reshape(preFlag(dataRStart:dataREnd),subLength_B,nSubR_B));
138
139
140 % OK. Loop over all six polarizations, flagging on the linear
141 % polarization, and also getting the smoothed overall RMS trends (which
142 % will be used in the next step).
1 143 for k=1:6
144
145 % Calculate the standard deviations!
146 % dataStdVec_A = std(detrend(reshape(data(dataRStart:dataREnd,k), subLength_A, nSubR_A)));
147 % dataStdVec_B = std(detrend(reshape(data(dataRStart:dataREnd,k), subLength_B, nSubR_B)));
0.43 6 148 dataStdVec_A = std(reshape(data(dataRStart:dataREnd,k), subLength_A, nSubR_A));
0.38 6 149 dataStdVec_B = std(reshape(data(dataRStart:dataREnd,k), subLength_B, nSubR_B));
150
151 % In case nSub is not an integer...
6 152 if nSub_B > nSubR_B
153 dataStdVec_A(1) = ...
154 std(data(1:dataRStart+subLength_A-1,k));
155 dataStdVec_A(end) = ...
156 std(data(dataREnd-subLength_A+1:end,k));
157
158 dataStdVec_B(1) = ...
159 std(data(1:dataRStart+subLength_B-1,k));
160 dataStdVec_B(end) = ...
161 std(data(dataREnd-subLength_B+1:end,k));
162 end
163
164
165 %-----
166 % So here's the actual short flagging part. Done in easy steps.
167 %-----
168
169 % Step 1: Clip immediate outliers using both arrays.
170 %-----
0.28 6 171 flagVec_A = stdClip(dataStdVec_A,3,nClip,1);
0.17 6 172 flagVec_B = stdClip(dataStdVec_B,3,nClip,1);
173
174
175 % Step 2: Ignoring outliers, calculate running median.
176 %-----
177
178 % Fold the positional flagging into the flag vector for this part:
179 % disp(size(flagVec_A));
180 % disp(size(repmat(preFlagR == 1,floor(subLength_B/subLength_A),1)));
0.01 6 181 flagVec_A_t = repmat(preFlagR == 1,floor(subLength_B/subLength_A),1);
0.10 6 182 flagVec_A = smooth((flagVec_A == 1) | flagVec_A_t(:)',40)' > 0;
0.04 6 183 flagVec_B = smooth((flagVec_B == 1) | (preFlagR == 1),20)' > 0;
184
185 % flagVec_A = repmat(flagVec_B,floor(subLength_B/subLength_A),1);
186 % flagVec_A = flagVec_A(:)';
187
188
189
190 % figure;
191 % plot(dataStdVec_A);
192 % hold on;
193 % plot(flagVec_A,'r');
194 % hold off;
195 %
196 % figure;
197 % plot(dataStdVec_B);
198 % hold on;
199 % plot(flagVec_B,'r');
200 % hold off;
201
202
0.46 6 203 runningMed_A = ...
204 padSmooth(xStd_A,dataStdVec_A,gaussKernelStd_A,flagVec_A, ...
205 [sLength_A sBuffStart_A sBuffEnd_A]);
0.20 6 206 runningMed_B = ...
207 padSmooth(xStd_B,dataStdVec_B,gaussKernelStd_B,flagVec_B, ...
208 [sLength_B sBuffStart_B sBuffEnd_B]);
209
210
211 % figure;
212 % plot(runningMed_A);
213 % figure;
214 % plot(runningMed_B);
215
216
217 % Step 3: Subtract running median.
218 %-----
6 219 dataStdVec_A = dataStdVec_A - runningMed_A';
6 220 dataStdVec_B = dataStdVec_B - runningMed_B';
221
222 % Step 4: Clip current outliers.
223 %-----
0.26 6 224 flagVec_A = stdClip(dataStdVec_A,5,nClip,0);
0.13 6 225 flagVec_B = stdClip(dataStdVec_B,5,nClip,0);
226
227
228 % Step 5: Normalize the standard deviation vectors.
229 %-----
0.01 6 230 dataStdNorm_A(:,k) = dataStdVec_A / std(dataStdVec_A(flagVec_A == 0));
0.01 6 231 dataStdNorm_B(:,k) = dataStdVec_B / std(dataStdVec_B(flagVec_B == 0));
232
233 % figure;
234 % plot(dataStdNorm_A(:,k));
235 % figure;
236 % plot(dataStdNorm_B(:,k));
237
238
239
240
241
242
243 % While we're here, let's go ahead and calculate another couple of
244 % standard deviation vectors.
245 % These ones are for use with the longer flagging.
246 % Note that, at this point, we go ahead and divide by the running
247 % median and subtract by the overall remaining mean (~1).
248
249 % Interpolate the running median a bit more.
1.09 6 250 runningMedLong = ...
251 interp1(((1:length(runningMed_A))' - 0.5) * subLength_A, ...
252 runningMed_A,(1:dLength),'pchip');
253
254 % figure;
255 % plot(runningMedLong);
256
257 % figure;
258 % plot(std(reshape(data(dataR2Start:dataR2End,k), ...
259 % subLength2_A, nSubR2_A)));
260 % hold on;
261 % plot(mean(reshape(runningMedLong(dataR2Start:dataR2End)', ...
262 % subLength2_A, nSubR2_A)),'r');
263 % plot(std(reshape(data(dataR2Start:dataR2End,k) ./ ...
264 % runningMedLong(dataR2Start:dataR2End)', ...
265 % subLength2_A, nSubR2_A)),'r');
266 % plot(std(reshape(data(dataR2Start:dataR2End,k) ./ ...
267 % runningMedLong(dataR2Start:dataR2End)', ...
268 % subLength2_A, nSubR2_A)) - 1,'g');
269 % hold off;
270
271 % disp(median(std(reshape(data(dataR2Start:dataR2End,k) ./ ...
272 % runningMedLong(dataR2Start:dataR2End)', ...
273 % subLength2_A, nSubR2_A))));
274 % input('adfa');
275
276
277
278 % dataStdVec2_A(:,k) = ...
279 % std(reshape(data(dataR2Start:dataR2End,k) ./ ...
280 % runningMedLong(dataR2Start:dataR2End)', ...
281 % subLength2_A, nSubR2_A));
282 %
283 % dataStdVec2_B(:,k) = ...
284 % std(reshape(data(dataR2Start:dataR2End,k) ./ ...
285 % runningMedLong(dataR2Start:dataR2End)', ...
286 % subLength2_B, nSubR2_B));
287
288
0.75 6 289 dataStdVec2_A(:,k) = ...
290 std(detrend(reshape(data(dataR2Start:dataR2End,k) ./ ...
291 runningMedLong(dataR2Start:dataR2End)', ...
292 subLength2_A, nSubR2_A)));
293
1.08 6 294 dataStdVec2_B(:,k) = ...
295 std(detrend(reshape(data(dataR2Start:dataR2End,k) ./ ...
296 runningMedLong(dataR2Start:dataR2End)', ...
297 subLength2_B, nSubR2_B)));
298
299 % figure;
300 % plot(dataStdVec2_A(:,k));
301
302
0.05 6 303 flagStdVec2_A = stdClip(dataStdVec2_A(:,k),1,nClip,1);
0.04 6 304 flagStdVec2_B = stdClip(dataStdVec2_B(:,k),1,nClip,1);
305
6 306 dataStdVec2_A(:,k) = dataStdVec2_A(:,k) - ...
307 mean(dataStdVec2_A(flagStdVec2_A == 0,k));
0.01 6 308 dataStdVec2_B(:,k) = dataStdVec2_B(:,k) - ...
309 mean(dataStdVec2_B(flagStdVec2_B == 0,k));
310
311
312 % In case nSub2_B is not an integer...
6 313 if nSub2_B > nSubR2_B
314 % dataStdVec2_A(1) = ...
315 % std(data(1:dataR2Start+subLength2_A-1,k) ./ ...
316 % runningMedLong(1:dataR2Start+subLength2_A-1)') - 1;
317 % dataStdVec2_A(end) = ...
318 % std(data(dataR2End-subLength2_A+1:end,k) ./ ...
319 % runningMedLong(dataR2End-subLength2_A+1:end)') - 1;
320 %
321 % dataStdVec2_B(1) = ...
322 % std(data(1:dataR2Start+subLength2_B-1,k) ./ ...
323 % runningMedLong(1:dataR2Start+subLength2_B-1)') - 1;
324 % dataStdVec2_B(end) = ...
325 % std(data(dataR2End-subLength2_B+1:end,k) ./ ...
326 % runningMedLong(dataR2End-subLength2_B+1:end)') - 1;
327
0.02 6 328 dataStdVec2_A(1) = ...
329 std(detrend(data(1:dataR2Start+subLength2_A-1,k) ./ ...
330 runningMedLong(1:dataR2Start+subLength2_A-1)')) - 1;
6 331 dataStdVec2_A(end) = ...
332 std(detrend(data(dataR2End-subLength2_A+1:end,k) ./ ...
333 runningMedLong(dataR2End-subLength2_A+1:end)')) - 1;
334
6 335 dataStdVec2_B(1) = ...
336 std(detrend(data(1:dataR2Start+subLength2_B-1,k) ./ ...
337 runningMedLong(1:dataR2Start+subLength2_B-1)')) - 1;
0.02 6 338 dataStdVec2_B(end) = ...
339 std(detrend(data(dataR2End-subLength2_B+1:end,k) ./ ...
340 runningMedLong(dataR2End-subLength2_B+1:end)')) - 1;
6 341 end
6 342 end
343
344
345 % Finish off the short flagging.
346 %%%%%%%%%%%%%%%%
347
348 % First off, we need to logically combine the polarization vectors.
349 % Further, we'll do a quick interpolation of the B vector to make it the
350 % same length as A.
0.01 1 351 dataStdLogic_A = max(min(dataStdNorm_A(:,2:2:4),[],2), ...
352 min(dataStdNorm_A(:,3:2:5),[],2));
353
0.01 1 354 dataStdI_A = mean(dataStdNorm_A(:,1:5:6),2);
355
356
1 357 dataStdLogic_B = repmat(max(min(dataStdNorm_B(:,2:2:4),[],2), ...
358 min(dataStdNorm_B(:,3:2:5),[],2))',subLength_B/subLength_A,1);
1 359 dataStdLogic_B = dataStdLogic_B(:);
360
0.01 1 361 dataStdI_B = repmat(mean(dataStdNorm_B(:,1:5:6),2)', ...
362 subLength_B/subLength_A,1);
1 363 dataStdI_B = dataStdI_B(:);
364
365 %figure;
366 %plot((1:length(dataStdI_A))*subLength_A,dataStdI_A);
367 %hold on;
368 %plot((1:length(dataStdI_A))*subLength_A,dataStdLogic_A,'r');
369 %plot((1:length(dataStdI_A))*subLength_A,dataStdI_B,'g');
370 %plot((1:length(dataStdI_A))*subLength_A,dataStdLogic_B,'c');
371 %hold off;
372
373
1 374 flagLogic = ...
375 ((dataStdLogic_A > params(1)) & ...
376 (dataStdLogic_A > params(2) * dataStdI_A) & ...
377 (dataStdLogic_B > params(2) * dataStdI_B) & ...
378 (dataStdLogic_B < params(3) * dataStdLogic_A)) | ...
379 dataStdLogic_A > params(4);
380
381 %figure;
382 %plot((1:length(dataStdI_A))*subLength_A,5*flagLogic,'k');
383 %hold off;
384
385 % Stretch it out.
0.01 1 386 flagRep = zeros(dLength,1);
1 387 flagRep(dataRStart:dataREnd) = ...
388 reshape(repmat(flagLogic',subLength_A,1),subLength_A*nSubR_A,1);
389
1 390 if dataRStart > 1
391 flagRep(1:dataRStart-1) = flagLogic(1);
392 flagRep(dataREnd+1:end) = flagLogic(end);
393 end
394
395 %plot(10*flagRep,'k');
396 %hold off;
397
398
399
400 % Now we do the longer flagging.
401 %%%%%%%%%%%%%%%%%
402
403 %figure;
404 %plot(dataStdVec2_A(:,1:5:6));
405 %figure;
406 %plot(dataStdVec2_B(:,1:5:6));
407
408 %display(params(9));
409 %display(params(8));
410
411 %figure;
412 %plot(dataStdVec2_B(:,1) > (params(9) * dataStdVec2_B(:,6)));
413 %hold on;
414 %plot((dataStdVec2_B(:,1) > params(8)) + 1.1,'r');
415
416
417 % First off, we need to smooth the vectors. At the same time, we'll add
418 % the matching polarization channels together.
1 419 dataStdI2_A = mean(dataStdVec2_A(:,1:5:6),2);
420 %dataStdLogic2_A = ...
421 % max(smooth((sum(dataStdVec2_A(:,2:2:4),2) / 2), subLength2_B/subLength2_A), ...
422 % smooth((sum(dataStdVec2_A(:,3:2:5),2) / 2), subLength2_B/subLength2_A));
1 423 dataStdLogic2_A = max(sum(dataStdVec2_A(:,2:2:4),2) / 2, ...
424 sum(dataStdVec2_A(:,3:2:5),2) / 2);
425
426 %dataStdI2_B = smooth(dataStdVec2_B(:,1),10);
1 427 dataStdI2_B = mean(dataStdVec2_B(:,1:5:6),2);
1 428 dataStdI2_B_max = max(dataStdVec2_B(:,1:5:6),[],2);
1 429 dataStdI2_B_min = min(dataStdVec2_B(:,1:5:6),[],2);
430
1 431 dataStdLogic2_B = max(sum(dataStdVec2_B(:,2:2:4),2) / 2, ...
432 sum(dataStdVec2_B(:,3:2:5),2) / 2);
433
1 434 dataStdLogic2_B = repmat(dataStdLogic2_B',subLength2_B/subLength2_A,1);
1 435 dataStdLogic2_B = dataStdLogic2_B(:);
436
1 437 dataStdI2_B = repmat(dataStdI2_B',subLength2_B/subLength2_A,1);
1 438 dataStdI2_B = dataStdI2_B(:);
439
1 440 dataStdI2_B_max = repmat(dataStdI2_B_max',subLength2_B/subLength2_A,1);
1 441 dataStdI2_B_max = dataStdI2_B_max(:);
1 442 dataStdI2_B_min = repmat(dataStdI2_B_min',subLength2_B/subLength2_A,1);
1 443 dataStdI2_B_min = dataStdI2_B_min(:);
444
445
446
447 %figure;
448 %plot(dataStdVec2_B);
449
450 %figure;
451 %plot((1:length(dataStdVec2_A))*subLength2_A,dataStdVec2_A);
452 %
453 %figure;
454 %plot((1:length(dataStdVec2_B))*subLength2_B,dataStdVec2_B);
455
456
457
458 %figure;
459 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdI2_A,'b');
460 %hold on;
461 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdLogic2_A,'r');
462 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdI2_B,'g');
463 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdLogic2_B,'c');
464
465
1 466 if params(11) > 0
1 467 for k=1:params(11)
1 468 dataStdI2_B = cat(2, dataStdI2_B, ...
469 cat(1,dataStdI2_B(1+k:end,1),zeros(k,1)), ...
470 cat(1,zeros(k,1),dataStdI2_B(1:end-k,1)));
1 471 end
472
1 473 dataStdI2_B = max(dataStdI2_B,[],2);
1 474 end
475
476 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdI2_B,'y');
477 %hold off;
478
479
480 % OK, now we flag on these fellows.
1 481 dataStdFlag = ((dataStdLogic2_A > params(5)) & ...
482 (dataStdLogic2_B > params(6)) & ...
483 (dataStdLogic2_B > params(7) * dataStdI2_B)) | ...
484 ((dataStdI2_B_max > params(8)) & ...
485 (dataStdI2_B_max > params(9) * dataStdI2_B_min));
486
487 %plot(((1:length(dataStdI2_B)) - 0.5)*subLength2_A,dataStdFlag,'k');
488 %hold off;
489
490 % Stretch it out.
0.01 1 491 flagStdRep = zeros(dLength,1);
0.02 1 492 flagStdRep(dataR2Start:dataR2End) = ...
493 reshape(repmat(dataStdFlag',subLength2_A,1),subLength2_A*nSubR2_A,1);
494
1 495 if dataR2Start > 1
1 496 flagStdRep(1:dataR2Start-1) = dataStdFlag(1);
1 497 flagStdRep(dataR2End+1:end) = dataStdFlag(end);
1 498 end
499
500
501
502 % Alright, let's put these two flags together.
503 % First we'll make sure they haven't already been flagged by position and
504 % make sure they're longer than 25 samples.
505 % Then flag their surroundings.
1 506 flagCombine = (flagRep | flagStdRep) & ~preFlag;
507
508 %figure;
509 %plot(flagCombine);
510 %hold on;
511
512 %figure;
513 %plot(flagCombine);
0.03 1 514 flagCombine = flagCombine & ...
515 cat(1,ones(12,1),flagCombine(1:end-12)) & ...
516 cat(1,flagCombine(13:end),ones(12,1));
517 %hold on;
518 %plot(flagCombine,'r');
519 %plot(flagCombine,'r');
520 %hold off;
521
1 522 if params(10) > 0
0.03 1 523 flag = (convn(double(flagCombine),ones(100*params(10),1),'same') > 0);
524 else
525 flag = (flagCombine > 0);
526 end
527
528 %flag = flagRep;
529
1 530 end
Other subfunctions in this file are not included in this listing.