00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <math.h>
00021 #include <string.h>
00022 #include <lal/FrequencySeries.h>
00023 #include <lal/LALStdlib.h>
00024 #include <lal/LALConstants.h>
00025 #include <lal/AVFactories.h>
00026 #include <lal/Sequence.h>
00027 #include <lal/TimeFreqFFT.h>
00028 #include <lal/Units.h>
00029 #include <lal/Window.h>
00030
00031 #include <lal/LALRCSID.h>
00032 NRCSID (AVERAGESPECTRUMC,"$Id: AverageSpectrum.c,v 1.17 2007/07/12 22:33:51 jolien Exp $");
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 int XLALREAL4ModifiedPeriodogram(
00044 REAL4FrequencySeries *periodogram,
00045 const REAL4TimeSeries *tseries,
00046 const REAL4Window *window,
00047 const REAL4FFTPlan *plan
00048 )
00049 {
00050 static const char *func = "XLALREAL4ModifiedPeriodogram";
00051 REAL4Sequence *work;
00052 REAL4 normfac;
00053 UINT4 k;
00054 int result;
00055
00056 if ( ! periodogram || ! tseries || ! plan )
00057 XLAL_ERROR( func, XLAL_EFAULT );
00058 if ( ! periodogram->data || ! tseries->data )
00059 XLAL_ERROR( func, XLAL_EINVAL );
00060 if ( tseries->deltaT <= 0.0 )
00061 XLAL_ERROR( func, XLAL_EINVAL );
00062 if ( periodogram->data->length != tseries->data->length/2 + 1 )
00063 XLAL_ERROR( func, XLAL_EBADLEN );
00064 if ( window )
00065 {
00066 if ( ! window->data )
00067 XLAL_ERROR( func, XLAL_EINVAL );
00068 if ( window->sumofsquares <= 0.0 )
00069 XLAL_ERROR( func, XLAL_EINVAL );
00070 if ( window->data->length != tseries->data->length )
00071 XLAL_ERROR( func, XLAL_EBADLEN );
00072 }
00073
00074
00075 if ( window )
00076 {
00077 UINT4 j;
00078
00079
00080 work = XLALCutREAL4Sequence( tseries->data, 0, tseries->data->length );
00081 if ( ! work )
00082 XLAL_ERROR( func, XLAL_EFUNC );
00083
00084
00085 for ( j = 0; j < tseries->data->length; ++j )
00086 work->data[j] *= window->data->data[j];
00087 }
00088 else
00089
00090 work = tseries->data;
00091
00092
00093
00094 result = XLALREAL4PowerSpectrum( periodogram->data, work, plan );
00095
00096 if ( window )
00097 XLALDestroyREAL4Sequence( work );
00098
00099 if ( result == XLAL_FAILURE )
00100 XLAL_ERROR( func, XLAL_EFUNC );
00101
00102
00103
00104 if ( window )
00105 normfac = tseries->deltaT / window->sumofsquares;
00106 else
00107 normfac = tseries->deltaT / tseries->data->length;
00108 for ( k = 0; k < periodogram->data->length; ++k )
00109 periodogram->data->data[k] *= normfac;
00110
00111
00112 periodogram->epoch = tseries->epoch;
00113 periodogram->f0 = tseries->f0;
00114 periodogram->deltaF = 1.0 / ( tseries->data->length * tseries->deltaT );
00115
00116
00117 if ( ! XLALUnitSquare( &periodogram->sampleUnits, &tseries->sampleUnits ) )
00118 XLAL_ERROR( func, XLAL_EFUNC );
00119 if ( ! XLALUnitMultiply( &periodogram->sampleUnits,
00120 &periodogram->sampleUnits, &lalSecondUnit ) )
00121 XLAL_ERROR( func, XLAL_EFUNC );
00122
00123 return 0;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 int XLALREAL8ModifiedPeriodogram(
00133 REAL8FrequencySeries *periodogram,
00134 const REAL8TimeSeries *tseries,
00135 const REAL8Window *window,
00136 const REAL8FFTPlan *plan
00137 )
00138 {
00139 static const char *func = "XLALREAL8ModifiedPeriodogram";
00140 REAL8Sequence *work;
00141 REAL8 normfac;
00142 UINT4 k;
00143 int result;
00144
00145 if ( ! periodogram || ! tseries || ! plan )
00146 XLAL_ERROR( func, XLAL_EFAULT );
00147 if ( ! periodogram->data || ! tseries->data )
00148 XLAL_ERROR( func, XLAL_EINVAL );
00149 if ( tseries->deltaT <= 0.0 )
00150 XLAL_ERROR( func, XLAL_EINVAL );
00151 if ( periodogram->data->length != tseries->data->length/2 + 1 )
00152 XLAL_ERROR( func, XLAL_EBADLEN );
00153 if ( window )
00154 {
00155 if ( ! window->data )
00156 XLAL_ERROR( func, XLAL_EINVAL );
00157 if ( window->sumofsquares <= 0.0 )
00158 XLAL_ERROR( func, XLAL_EINVAL );
00159 if ( window->data->length != tseries->data->length )
00160 XLAL_ERROR( func, XLAL_EBADLEN );
00161 }
00162
00163
00164 if ( window )
00165 {
00166 UINT4 j;
00167
00168
00169 work = XLALCutREAL8Sequence( tseries->data, 0, tseries->data->length );
00170 if ( ! work )
00171 XLAL_ERROR( func, XLAL_EFUNC );
00172
00173
00174 for ( j = 0; j < tseries->data->length; ++j )
00175 work->data[j] *= window->data->data[j];
00176 }
00177 else
00178
00179 work = tseries->data;
00180
00181
00182
00183 result = XLALREAL8PowerSpectrum( periodogram->data, work, plan );
00184
00185 if ( window )
00186 XLALDestroyREAL8Sequence( work );
00187
00188 if ( result == XLAL_FAILURE )
00189 XLAL_ERROR( func, XLAL_EFUNC );
00190
00191
00192
00193 if ( window )
00194 normfac = tseries->deltaT / window->sumofsquares;
00195 else
00196 normfac = tseries->deltaT / tseries->data->length;
00197 for ( k = 0; k < periodogram->data->length; ++k )
00198 periodogram->data->data[k] *= normfac;
00199
00200
00201 periodogram->epoch = tseries->epoch;
00202 periodogram->f0 = tseries->f0;
00203 periodogram->deltaF = 1.0 / ( tseries->data->length * tseries->deltaT );
00204
00205
00206 if ( ! XLALUnitSquare( &periodogram->sampleUnits, &tseries->sampleUnits ) )
00207 XLAL_ERROR( func, XLAL_EFUNC );
00208 if ( ! XLALUnitMultiply( &periodogram->sampleUnits,
00209 &periodogram->sampleUnits, &lalSecondUnit ) )
00210 XLAL_ERROR( func, XLAL_EFUNC );
00211
00212 return 0;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 int XLALREAL4AverageSpectrumWelch(
00227 REAL4FrequencySeries *spectrum,
00228 const REAL4TimeSeries *tseries,
00229 UINT4 seglen,
00230 UINT4 stride,
00231 const REAL4Window *window,
00232 const REAL4FFTPlan *plan
00233 )
00234 {
00235 static const char *func = "XLALREAL4AverageSpectrumWelch";
00236 REAL4FrequencySeries *work;
00237 REAL4Sequence sequence;
00238 REAL4TimeSeries tseriescopy;
00239 UINT4 numseg;
00240 UINT4 seg;
00241 UINT4 k;
00242
00243 if ( ! spectrum || ! tseries || ! plan )
00244 XLAL_ERROR( func, XLAL_EFAULT );
00245 if ( ! spectrum->data || ! tseries->data )
00246 XLAL_ERROR( func, XLAL_EINVAL );
00247 if ( tseries->deltaT <= 0.0 )
00248 XLAL_ERROR( func, XLAL_EINVAL );
00249
00250
00251 sequence = *tseries->data;
00252 tseriescopy = *tseries;
00253 tseriescopy.data = &sequence;
00254 tseriescopy.data->length = seglen;
00255
00256 numseg = 1 + (tseries->data->length - seglen)/stride;
00257
00258
00259
00260 if ( (numseg - 1)*stride + seglen != tseries->data->length )
00261 XLAL_ERROR( func, XLAL_EBADLEN );
00262 if ( spectrum->data->length != seglen/2 + 1 )
00263 XLAL_ERROR( func, XLAL_EBADLEN );
00264
00265
00266 if ( window )
00267 {
00268 if ( ! window->data )
00269 XLAL_ERROR( func, XLAL_EINVAL );
00270 if ( window->sumofsquares <= 0.0 )
00271 XLAL_ERROR( func, XLAL_EINVAL );
00272 if ( window->data->length != seglen )
00273 XLAL_ERROR( func, XLAL_EBADLEN );
00274 }
00275
00276
00277 memset( spectrum->data->data, 0,
00278 spectrum->data->length * sizeof( *spectrum->data->data ) );
00279
00280
00281 work = XLALCutREAL4FrequencySeries( spectrum, 0, spectrum->data->length );
00282 if( ! work )
00283 XLAL_ERROR( func, XLAL_EFUNC );
00284
00285 for ( seg = 0; seg < numseg; seg++, tseriescopy.data->data += stride )
00286 {
00287
00288 if ( XLALREAL4ModifiedPeriodogram( work, &tseriescopy, window, plan ) == XLAL_FAILURE )
00289 {
00290 XLALDestroyREAL4FrequencySeries( work );
00291 XLAL_ERROR( func, XLAL_EFUNC );
00292 }
00293
00294
00295 for ( k = 0; k < spectrum->data->length; ++k )
00296 spectrum->data->data[k] += work->data->data[k];
00297 }
00298
00299
00300 spectrum->epoch = work->epoch;
00301 spectrum->f0 = work->f0;
00302 spectrum->deltaF = work->deltaF;
00303 spectrum->sampleUnits = work->sampleUnits;
00304
00305
00306 for ( k = 0; k < spectrum->data->length; ++k )
00307 spectrum->data->data[k] /= numseg;
00308
00309
00310 XLALDestroyREAL4FrequencySeries( work );
00311
00312 return 0;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 int XLALREAL8AverageSpectrumWelch(
00326 REAL8FrequencySeries *spectrum,
00327 const REAL8TimeSeries *tseries,
00328 UINT4 seglen,
00329 UINT4 stride,
00330 const REAL8Window *window,
00331 const REAL8FFTPlan *plan
00332 )
00333 {
00334 static const char *func = "XLALREAL8AverageSpectrumWelch";
00335 REAL8FrequencySeries *work;
00336 REAL8Sequence sequence;
00337 REAL8TimeSeries tseriescopy;
00338 UINT4 numseg;
00339 UINT4 seg;
00340 UINT4 k;
00341
00342 if ( ! spectrum || ! tseries || ! plan )
00343 XLAL_ERROR( func, XLAL_EFAULT );
00344 if ( ! spectrum->data || ! tseries->data )
00345 XLAL_ERROR( func, XLAL_EINVAL );
00346 if ( tseries->deltaT <= 0.0 )
00347 XLAL_ERROR( func, XLAL_EINVAL );
00348
00349
00350 sequence = *tseries->data;
00351 tseriescopy = *tseries;
00352 tseriescopy.data = &sequence;
00353 tseriescopy.data->length = seglen;
00354
00355 numseg = 1 + (tseries->data->length - seglen)/stride;
00356
00357
00358
00359 if ( (numseg - 1)*stride + seglen != tseries->data->length )
00360 XLAL_ERROR( func, XLAL_EBADLEN );
00361 if ( spectrum->data->length != seglen/2 + 1 )
00362 XLAL_ERROR( func, XLAL_EBADLEN );
00363
00364
00365 if ( window )
00366 {
00367 if ( ! window->data )
00368 XLAL_ERROR( func, XLAL_EINVAL );
00369 if ( window->sumofsquares <= 0.0 )
00370 XLAL_ERROR( func, XLAL_EINVAL );
00371 if ( window->data->length != seglen )
00372 XLAL_ERROR( func, XLAL_EBADLEN );
00373 }
00374
00375
00376 memset( spectrum->data->data, 0,
00377 spectrum->data->length * sizeof( *spectrum->data->data ) );
00378
00379
00380 work = XLALCutREAL8FrequencySeries( spectrum, 0, spectrum->data->length );
00381 if( ! work )
00382 XLAL_ERROR( func, XLAL_EFUNC );
00383
00384 for ( seg = 0; seg < numseg; seg++, tseriescopy.data->data += stride )
00385 {
00386
00387 if ( XLALREAL8ModifiedPeriodogram( work, &tseriescopy, window, plan ) == XLAL_FAILURE )
00388 {
00389 XLALDestroyREAL8FrequencySeries( work );
00390 XLAL_ERROR( func, XLAL_EFUNC );
00391 }
00392
00393
00394 for ( k = 0; k < spectrum->data->length; ++k )
00395 spectrum->data->data[k] += work->data->data[k];
00396 }
00397
00398
00399 spectrum->epoch = work->epoch;
00400 spectrum->f0 = work->f0;
00401 spectrum->deltaF = work->deltaF;
00402 spectrum->sampleUnits = work->sampleUnits;
00403
00404
00405 for ( k = 0; k < spectrum->data->length; ++k )
00406 spectrum->data->data[k] /= numseg;
00407
00408
00409 XLALDestroyREAL8FrequencySeries( work );
00410
00411 return 0;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 REAL8 XLALMedianBias( UINT4 nn )
00423 {
00424 const UINT4 nmax = 1000;
00425 REAL8 ans = 1;
00426 UINT4 n = (nn - 1)/2;
00427 UINT4 i;
00428
00429 if ( nn >= nmax )
00430 return LAL_LN2;
00431
00432 for ( i = 1; i <= n; ++i )
00433 {
00434 ans -= 1.0/(2*i);
00435 ans += 1.0/(2*i + 1);
00436 }
00437
00438 return ans;
00439 }
00440
00441
00442 static void median_cleanup_REAL4( REAL4FrequencySeries *work, UINT4 n )
00443 {
00444 int saveErrno = xlalErrno;
00445 UINT4 i;
00446 for ( i = 0; i < n; ++i )
00447 if ( work[i].data )
00448 XLALDestroyREAL4Vector( work[i].data );
00449 LALFree( work );
00450 xlalErrno = saveErrno;
00451 return;
00452 }
00453 static void median_cleanup_REAL8( REAL8FrequencySeries *work, UINT4 n )
00454 {
00455 int saveErrno = xlalErrno;
00456 UINT4 i;
00457 for ( i = 0; i < n; ++i )
00458 if ( work[i].data )
00459 XLALDestroyREAL8Vector( work[i].data );
00460 LALFree( work );
00461 xlalErrno = saveErrno;
00462 return;
00463 }
00464
00465
00466 static int compare_REAL4( const void *p1, const void *p2 )
00467 {
00468 REAL4 x1 = *(const REAL4 *)p1;
00469 REAL4 x2 = *(const REAL4 *)p2;
00470 return (x1 > x2) - (x1 < x2);
00471 }
00472 static int compare_REAL8( const void *p1, const void *p2 )
00473 {
00474 REAL8 x1 = *(const REAL8 *)p1;
00475 REAL8 x2 = *(const REAL8 *)p2;
00476 return (x1 > x2) - (x1 < x2);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 int XLALREAL4AverageSpectrumMedian(
00490 REAL4FrequencySeries *spectrum,
00491 const REAL4TimeSeries *tseries,
00492 UINT4 seglen,
00493 UINT4 stride,
00494 const REAL4Window *window,
00495 const REAL4FFTPlan *plan
00496 )
00497 {
00498 static const char *func = "XLALREAL4AverageSpectrumMedian";
00499 REAL4FrequencySeries *work;
00500 REAL4 *bin;
00501 REAL4 biasfac;
00502 REAL4 normfac;
00503 UINT4 reclen;
00504 UINT4 numseg;
00505 UINT4 seg;
00506 UINT4 k;
00507
00508 if ( ! spectrum || ! tseries || ! plan )
00509 XLAL_ERROR( func, XLAL_EFAULT );
00510 if ( ! spectrum->data || ! tseries->data )
00511 XLAL_ERROR( func, XLAL_EINVAL );
00512 if ( tseries->deltaT <= 0.0 )
00513 XLAL_ERROR( func, XLAL_EINVAL );
00514
00515 reclen = tseries->data->length;
00516 numseg = 1 + (reclen - seglen)/stride;
00517
00518
00519
00520 if ( (numseg - 1)*stride + seglen != reclen )
00521 XLAL_ERROR( func, XLAL_EBADLEN );
00522 if ( spectrum->data->length != seglen/2 + 1 )
00523 XLAL_ERROR( func, XLAL_EBADLEN );
00524
00525
00526 if ( window )
00527 {
00528 if ( ! window->data )
00529 XLAL_ERROR( func, XLAL_EINVAL );
00530 if ( window->sumofsquares <= 0.0 )
00531 XLAL_ERROR( func, XLAL_EINVAL );
00532 if ( window->data->length != seglen )
00533 XLAL_ERROR( func, XLAL_EBADLEN );
00534 }
00535
00536
00537 work = LALCalloc( numseg, sizeof( *work ) );
00538 if ( ! work )
00539 XLAL_ERROR( func, XLAL_ENOMEM );
00540 for ( seg = 0; seg < numseg; ++seg )
00541 {
00542 work[seg].data = XLALCreateREAL4Vector( spectrum->data->length );
00543 if ( ! work[seg].data )
00544 {
00545 median_cleanup_REAL4( work, numseg );
00546 XLAL_ERROR( func, XLAL_EFUNC );
00547 }
00548 }
00549
00550 for ( seg = 0; seg < numseg; ++seg )
00551 {
00552 REAL4Vector savevec;
00553 int code;
00554
00555
00556 savevec = *tseries->data;
00557
00558
00559 tseries->data->length = seglen;
00560 tseries->data->data += seg * stride;
00561
00562
00563 code = XLALREAL4ModifiedPeriodogram( work + seg, tseries, window, plan );
00564
00565
00566 *tseries->data = savevec;
00567
00568
00569 if ( code == XLAL_FAILURE )
00570 {
00571 median_cleanup_REAL4( work, numseg );
00572 XLAL_ERROR( func, XLAL_EFUNC );
00573 }
00574 }
00575
00576
00577 bin = LALMalloc( numseg * sizeof( *bin ) );
00578 if ( ! bin )
00579 {
00580 median_cleanup_REAL4( work, numseg );
00581 XLAL_ERROR( func, XLAL_ENOMEM );
00582 }
00583
00584
00585 biasfac = XLALMedianBias( numseg );
00586
00587
00588 normfac = 1.0 / biasfac;
00589
00590
00591 for ( k = 0; k < spectrum->data->length; ++k )
00592 {
00593
00594 for ( seg = 0; seg < numseg; ++seg )
00595 bin[seg] = work[seg].data->data[k];
00596
00597
00598 qsort( bin, numseg, sizeof( *bin ), compare_REAL4 );
00599 if ( numseg % 2 )
00600 spectrum->data->data[k] = bin[numseg/2];
00601 else
00602 spectrum->data->data[k] = 0.5*(bin[numseg/2-1] + bin[numseg/2]);
00603
00604
00605 spectrum->data->data[k] *= normfac;
00606 }
00607
00608
00609 spectrum->epoch = work->epoch;
00610 spectrum->f0 = work->f0;
00611 spectrum->deltaF = work->deltaF;
00612 spectrum->sampleUnits = work->sampleUnits;
00613
00614
00615 LALFree( bin );
00616 median_cleanup_REAL4( work, numseg );
00617
00618 return 0;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 int XLALREAL8AverageSpectrumMedian(
00631 REAL8FrequencySeries *spectrum,
00632 const REAL8TimeSeries *tseries,
00633 UINT4 seglen,
00634 UINT4 stride,
00635 const REAL8Window *window,
00636 const REAL8FFTPlan *plan
00637 )
00638 {
00639 static const char *func = "XLALREAL8AverageSpectrumMedian";
00640 REAL8FrequencySeries *work;
00641 REAL8 *bin;
00642 REAL8 biasfac;
00643 REAL8 normfac;
00644 UINT4 reclen;
00645 UINT4 numseg;
00646 UINT4 seg;
00647 UINT4 k;
00648
00649 if ( ! spectrum || ! tseries || ! plan )
00650 XLAL_ERROR( func, XLAL_EFAULT );
00651 if ( ! spectrum->data || ! tseries->data )
00652 XLAL_ERROR( func, XLAL_EINVAL );
00653 if ( tseries->deltaT <= 0.0 )
00654 XLAL_ERROR( func, XLAL_EINVAL );
00655
00656 reclen = tseries->data->length;
00657 numseg = 1 + (reclen - seglen)/stride;
00658
00659
00660
00661 if ( (numseg - 1)*stride + seglen != reclen )
00662 XLAL_ERROR( func, XLAL_EBADLEN );
00663 if ( spectrum->data->length != seglen/2 + 1 )
00664 XLAL_ERROR( func, XLAL_EBADLEN );
00665
00666
00667 if ( window )
00668 {
00669 if ( ! window->data )
00670 XLAL_ERROR( func, XLAL_EINVAL );
00671 if ( window->sumofsquares <= 0.0 )
00672 XLAL_ERROR( func, XLAL_EINVAL );
00673 if ( window->data->length != seglen )
00674 XLAL_ERROR( func, XLAL_EBADLEN );
00675 }
00676
00677
00678 work = LALCalloc( numseg, sizeof( *work ) );
00679 if ( ! work )
00680 XLAL_ERROR( func, XLAL_ENOMEM );
00681 for ( seg = 0; seg < numseg; ++seg )
00682 {
00683 work[seg].data = XLALCreateREAL8Vector( spectrum->data->length );
00684 if ( ! work[seg].data )
00685 {
00686 median_cleanup_REAL8( work, numseg );
00687 XLAL_ERROR( func, XLAL_EFUNC );
00688 }
00689 }
00690
00691 for ( seg = 0; seg < numseg; ++seg )
00692 {
00693 REAL8Vector savevec;
00694 int code;
00695
00696
00697 savevec = *tseries->data;
00698
00699
00700 tseries->data->length = seglen;
00701 tseries->data->data += seg * stride;
00702
00703
00704 code = XLALREAL8ModifiedPeriodogram( work + seg, tseries, window, plan );
00705
00706
00707 *tseries->data = savevec;
00708
00709
00710 if ( code == XLAL_FAILURE )
00711 {
00712 median_cleanup_REAL8( work, numseg );
00713 XLAL_ERROR( func, XLAL_EFUNC );
00714 }
00715 }
00716
00717
00718 bin = LALMalloc( numseg * sizeof( *bin ) );
00719 if ( ! bin )
00720 {
00721 median_cleanup_REAL8( work, numseg );
00722 XLAL_ERROR( func, XLAL_ENOMEM );
00723 }
00724
00725
00726 biasfac = XLALMedianBias( numseg );
00727
00728
00729 normfac = 1.0 / biasfac;
00730
00731
00732 for ( k = 0; k < spectrum->data->length; ++k )
00733 {
00734
00735 for ( seg = 0; seg < numseg; ++seg )
00736 bin[seg] = work[seg].data->data[k];
00737
00738
00739 qsort( bin, numseg, sizeof( *bin ), compare_REAL8 );
00740 if ( numseg % 2 )
00741 spectrum->data->data[k] = bin[numseg/2];
00742 else
00743 spectrum->data->data[k] = 0.5*(bin[numseg/2-1] + bin[numseg/2]);
00744
00745
00746 spectrum->data->data[k] *= normfac;
00747 }
00748
00749
00750 spectrum->epoch = work->epoch;
00751 spectrum->f0 = work->f0;
00752 spectrum->deltaF = work->deltaF;
00753 spectrum->sampleUnits = work->sampleUnits;
00754
00755
00756 LALFree( bin );
00757 median_cleanup_REAL8( work, numseg );
00758
00759 return 0;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 static void median_mean_cleanup_REAL4( REAL4FrequencySeries *even, REAL4FrequencySeries *odd, UINT4 n )
00772 {
00773 int saveErrno = xlalErrno;
00774 UINT4 i;
00775 for ( i = 0; i < n; ++i )
00776 {
00777 if ( even[i].data )
00778 XLALDestroyREAL4Vector( even[i].data );
00779 if ( odd[i].data )
00780 XLALDestroyREAL4Vector( odd[i].data );
00781 }
00782 LALFree( even );
00783 LALFree( odd );
00784 xlalErrno = saveErrno;
00785 return;
00786 }
00787 static void median_mean_cleanup_REAL8( REAL8FrequencySeries *even, REAL8FrequencySeries *odd, UINT4 n )
00788 {
00789 int saveErrno = xlalErrno;
00790 UINT4 i;
00791 for ( i = 0; i < n; ++i )
00792 {
00793 if ( even[i].data )
00794 XLALDestroyREAL8Vector( even[i].data );
00795 if ( odd[i].data )
00796 XLALDestroyREAL8Vector( odd[i].data );
00797 }
00798 LALFree( even );
00799 LALFree( odd );
00800 xlalErr