Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ComputeStrain.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Xavier Siemens
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20#include <complex.h>
21#include <math.h>
22#include <stdio.h>
23#include <lal/LALStdlib.h>
24#include <lal/LALConstants.h>
25#include <lal/Calibration.h>
26#include <lal/LALDatatypes.h>
27#include <lal/LALStdlib.h>
28#include <lal/LALStdio.h>
29#include <lal/AVFactories.h>
30#include <lal/Window.h>
31#include <lal/BandPassTimeSeries.h>
32#include <lal/TimeFreqFFT.h>
33#include <lal/RealFFT.h>
34#include <lal/AVFactories.h>
35#include <lal/FrequencySeries.h>
36#include <lal/TimeSeries.h>
37
38#include <gsl/gsl_interp.h>
39#include <gsl/gsl_spline.h>
40
41#define MAXALPHAS 10000
42
43#define N_FIR_LP_ALPHAS 8192
44#define fhigh_FIRLP_ALPHAS 0.00001220703125
45
46#define N_FIR_LP 100
47/* #define fhigh_FIRLP .6103515625 */
48#define fhigh_FIRLP .9
49
50#define N_FIR_HP 2000
51#define fhigh_FIRHP 0.00244140625
52
53
54
55/* Local helper functions, defined static so they cannot be used outside. */
57static void check_nans_infs(LALStatus *status, StrainIn *input);
58#if 0
59static void remove_transients(StrainIn *input);
60#endif
61
62
66 StrainIn *input
67 )
68{
69/* Inverse sensing, servo, analog actuation, digital x
70actuation digital y actuation */
71static REAL8TimeSeries ALPHAS,upALPHAS;
72int p;
73REAL8IIRFilter HPFIR;
74REAL8IIRFilter ALPHASLPFIR;
75
78
80
81 /* remove_transients(input); */
82 /* commented out for the moment, because looking directly in the
83 * gravitational wave channel for noise is dangerous and should be
84 * done with great great care. */
85
86 check_nans_infs(status, input);
87 if (! status->statusPtr) return;
88
89 LALGetFactors(status->statusPtr, output, input);
91
92 LALMakeFIRHP(status->statusPtr, &HPFIR);
94
95 /* copy DARM_ERR input into residual strain as double */
96 for (p=0; p<(int)output->hR.data->length; p++)
97 {
98 output->hR.data->data[p]=input->DARM_ERR.data->data[p];
99 }
100
101 if (input->darmctrl)
102 {
103 /* copy DARM_CTRL input into control strain as double */
104 for (p=0; p<(int)output->hC.data->length; p++)
105 {
106 output->hC.data->data[p]=input->DARM.data->data[p];
107 }
108 /* set to 0 the sampleUnits: they are not used anyway, and
109 * leaving them uninitialized can cause a mess */
110 output->hC.sampleUnits.powerOfTen = 0;
111 for (p=0; p < LALNumUnits; p++)
112 {
113 output->hC.sampleUnits.unitNumerator[p] = 0;
114 output->hC.sampleUnits.unitDenominatorMinusOne[p] = 0;
115 }
116 }
117 else
118 {
119 /* If DARM_ERR only calibration copy DARM_ERR data into control
120 signal */
121 for (p=0; p<(int)output->hC.data->length; p++)
122 {
123 output->hC.data->data[p]=input->DARM_ERR.data->data[p];
124 }
125 }
126
127 /* unit impulse */
128 if (input->delta)
129 {
130 for (p=0; p<(int)output->hR.data->length; p++)
131 {
132 output->hR.data->data[p]=0;
133 }
134 output->hR.data->data[output->hC.data->length/2]=1.0;
135 }
136
137 /* unit impulse */
138 if (input->delta)
139 {
140 for (p=0; p<(int)output->hC.data->length; p++)
141 {
142 output->hC.data->data[p]=0;
143 }
144 output->hC.data->data[output->hC.data->length/2]=1.0;
145 }
146
147 /* ---------- Compute Residual Strain -------------*/
148
149 /* check that we are using a recent filter file (without an upsampling of darm_err) */
150 if (input->CinvUSF != 1)
151 {
152 ABORT(status, 117, "Upsampling factor != 1, this is not a good filters file.");
153 }
154
155 /* apply delay (actually an advance) */
156 for (p=0; p<(int)output->hR.data->length+input->CinvDelay; p++){
157 output->hR.data->data[p]=output->hR.data->data[p-input->CinvDelay];
158 }
159
160 /* Filter through inverse of sensing function */
161 XLALFIRFilter(&(output->hR), input->Cinv);
162
163 /* Create time series that hold alpha time series and upsampled alpha time-series */
164 LALDCreateVector(status->statusPtr,&ALPHAS.data,output->alpha.data->length);
166 LALDCreateVector(status->statusPtr,&upALPHAS.data,input->DARM_ERR.data->length);
168 upALPHAS.deltaT=input->DARM_ERR.deltaT;
169
170 /* copy factors into time series */
171 for (p=0; p<(int)ALPHAS.data->length; p++)
172 {
173 REAL8 r = creal(output->alphabeta.data->data[p]);
174
175 /* check alphabeta: If values are outside bounds we replace
176 * factors with the last one, or with 1 if it is the first */
177 if ( (r < 0.8) || (r > 1.2) || (isnan(r)) || isinf(r))
178 {
179 if (p > 0)
180 ALPHAS.data->data[p] = ALPHAS.data->data[p-1];
181 else
182 ALPHAS.data->data[p] = 1.0;
183 }
184 else
185 {
186 ALPHAS.data->data[p] = r; /* this is the "standard" nice case */
187 }
188 }
189
190 /* upsample using a linear interpolation */
191 if(XLALUpsampleLinear(&upALPHAS, &ALPHAS, (int) (output->alphabeta.deltaT/input->DARM_ERR.deltaT+0.5)))
192 {
193 ABORT(status,117,"Broke upsampling Alphas");
194 }
195
196 /* Generate alphas LP filter to smooth linearly interpolated factors time series */
197 LALMakeFIRLPALPHAS(status->statusPtr, &ALPHASLPFIR);
199
200 /* Note that I do not compensate for delay
201 if factors are computed every second then everything is fine */
202 if (input->fftconv)
203 {
204 LALFFTFIRFilter(status->statusPtr,&upALPHAS,&(ALPHASLPFIR));
206 }
207 else
208 {
209 XLALFIRFilter(&upALPHAS,&(ALPHASLPFIR));
210 }
211
212 /* finally we divide by alpha*beta */
213 if (input->usefactors)
214 {
215 if(XLALDivideTimeSeries(&(output->hR), &upALPHAS))
216 {
217 ABORT(status,116,"Broke at hR/alpha");
218 }
219 }
220
221 if (input->outalphas)
222 {
223 /* set output to alphas */
224 for (p=0; p<(int)output->hR.data->length; p++) {
225 output->hR.data->data[p]=upALPHAS.data->data[p];
226 }
227 }
228
229 /* destroy low and high pass filters */
230 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.directCoef));
232 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.recursCoef));
234 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.history));
236
237 /* destroy both alphas time series */
238 LALDDestroyVector(status->statusPtr,&upALPHAS.data);
240 LALDDestroyVector(status->statusPtr,&ALPHAS.data);
242
243 /* ---------- Compute Control Strain -------------*/
244 /* apply advance to compensate for FIR delay */
245 for (p=0; p<(int)output->hC.data->length-(2*N_FIR_HP); p++){
246 output->hC.data->data[p]=output->hC.data->data[p+(2*N_FIR_HP)];
247 }
248
249 /* then high-pass filter DARM_CTRL */
250 if (input->fftconv)
251 {
252 LALFFTFIRFilter(status->statusPtr,&(output->hC),&(HPFIR));
254 LALFFTFIRFilter(status->statusPtr,&(output->hC),&(HPFIR));
256 }
257 else
258 {
259 XLALFIRFilter(&(output->hC),&(HPFIR));
260 XLALFIRFilter(&(output->hC),&(HPFIR));
261 }
262
263 if (input->darmctrl)
264 {
265 /* Filter through anti-whitening */
266 if (input->fftconv)
267 {
268 LALFFTFIRFilter(status->statusPtr,&(output->hC), input->AW);
270 }
271 else
272 {
273 XLALFIRFilter(&(output->hC), input->AW);
274 }
275 }else
276 {
277 /* Filter through servo */
278 if (input->fftconv)
279 {
280 LALFFTFIRFilter(status->statusPtr,&(output->hC), input->D);
282 }
283 else
284 {
285 XLALFIRFilter(&(output->hC), input->D);
286 }
287
288 /* At this point I have something very similar to darm_ctrl in hC */
289 /* add the calibration lines */
290 if (!input->delta && (input->DARM_ERR.deltaT == input->EXC.deltaT))
291 {
292 int k;
293 for(k = 0; k < (int)output->hC.data->length; k++){
294 output->hC.data->data[k] += input->EXC.data->data[k];
295 }
296 }
297 else
298 {
299 fprintf(stdout, "Warning: Not adding calibration lines to control signal.\n");
300 }
301 }
302
303 /* Filter through analog actuation */
304 if (input->fftconv)
305 {
306 LALFFTFIRFilter(status->statusPtr,&(output->hC), input->A);
308 }
309 else
310 {
311 XLALFIRFilter(&(output->hC), input->A);
312 }
313
314 /* ---------- Compute Net Strain -------------*/
315 /* add control and residual signals and voila' */
316 for (p=0; p< (int)output->h.data->length; p++){
317 output->h.data->data[p] = output->hC.data->data[p]+output->hR.data->data[p];
318 }
319 /* ------------------------------------------*/
320
321 /* destroy high pass filter */
322 LALDDestroyVector(status->statusPtr,&(HPFIR.directCoef));
324 LALDDestroyVector(status->statusPtr,&(HPFIR.recursCoef));
326 LALDDestroyVector(status->statusPtr,&(HPFIR.history));
328
330 RETURN( status );
331
332}
333
334/*******************************************************************************/
335
337{
338 int N=2*N_FIR_LP+1,l;
339 int k[2*N_FIR_LP+1];
340 REAL8 fN=fhigh_FIRLP/USF;
341
344
345 LPFIR->directCoef=NULL;
346 LPFIR->recursCoef=NULL;
347 LPFIR->history=NULL;
348
349 LALDCreateVector(status->statusPtr,&(LPFIR->directCoef),N);
351 LALDCreateVector(status->statusPtr,&(LPFIR->recursCoef),N);
353 LALDCreateVector(status->statusPtr,&(LPFIR->history),N-1);
355
356 for(l=0;l<N;l++) LPFIR->recursCoef->data[l]=0.0;
357 for(l=0;l<N-1;l++) LPFIR->history->data[l]=0.0;
358
359 for (l=0; l<N;l++)
360 {
361 k[l]=l-N_FIR_LP;
362 if(k[l] != 0)
363 {
364 LPFIR->directCoef->data[l]=(sin(LAL_PI*fN*k[l])/(LAL_PI*k[l]))*
365 exp(-0.5*pow(3.0*(double)k[l]/(double)N_FIR_LP,2));
366 }else{
367 LPFIR->directCoef->data[l]=fN;
368 }
369 }
370
371
372/* for(l=0;l<N;l++) fprintf(stdout,"%1.16e\n", LPFIR->directCoef->data[l]); */
373
375 RETURN( status );
376
377}
378
379/*******************************************************************************/
380
382{
383 int N=2*N_FIR_LP_ALPHAS+1,l;
384 int k[2*N_FIR_LP_ALPHAS+1];
386
389
390 LPFIR->directCoef=NULL;
391 LPFIR->recursCoef=NULL;
392 LPFIR->history=NULL;
393
394 LALDCreateVector(status->statusPtr,&(LPFIR->directCoef),N);
396 LALDCreateVector(status->statusPtr,&(LPFIR->recursCoef),N);
398 LALDCreateVector(status->statusPtr,&(LPFIR->history),N-1);
400
401 for(l=0;l<N;l++) LPFIR->recursCoef->data[l]=0.0;
402 for(l=0;l<N-1;l++) LPFIR->history->data[l]=0.0;
403
404 for (l=0; l<N;l++)
405 {
406 k[l]=l-N_FIR_LP_ALPHAS;
407 if(k[l] != 0)
408 {
409 LPFIR->directCoef->data[l]=(sin(LAL_PI*fN*k[l])/(LAL_PI*k[l]))*
410 exp(-0.5*pow(3.0*(double)k[l]/(double)N_FIR_LP_ALPHAS,2))/8.318081379762647e-02;
411 }else{
412 LPFIR->directCoef->data[l]=fN;
413 }
414 }
415
416
417/* for(l=0;l<N;l++) fprintf(stdout,"%1.16e\n", LPFIR->directCoef->data[l]); */
418
420 RETURN( status );
421
422}
423/*******************************************************************************/
424
426{
427 int N=2*N_FIR_HP+1,l;
428 int k[2*N_FIR_HP+1];
430
433
434 HPFIR->directCoef=NULL;
435 HPFIR->recursCoef=NULL;
436 HPFIR->history=NULL;
437
438 LALDCreateVector(status->statusPtr,&(HPFIR->directCoef),N);
440 LALDCreateVector(status->statusPtr,&(HPFIR->recursCoef),N);
442 LALDCreateVector(status->statusPtr,&(HPFIR->history),N-1);
444
445 for(l=0;l<N;l++) HPFIR->recursCoef->data[l]=0.0;
446 for(l=0;l<N-1;l++) HPFIR->history->data[l]=0.0;
447
448 for (l=0; l<N;l++)
449 {
450 k[l]=l-N_FIR_HP;
451 if(k[l] != 0)
452 {
453 HPFIR->directCoef->data[l]=(sin(LAL_PI*k[l])-sin(LAL_PI*fN*k[l]))/(LAL_PI*k[l])*
454 exp(-0.5*pow(3.0*(double)k[l]/(double)N_FIR_HP,2));
455 }else{
456 HPFIR->directCoef->data[l]=1.0-fN;
457 }
458 }
459
460
461/* for(l=0;l<N;l++) fprintf(stdout,"%1.16e\n", HPFIR->directCoef->data[l]); */
462
464 RETURN( status );
465
466}
467
468/*******************************************************************************/
469
470int XLALUpsample(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
471{
472 int n;
473
474 /* Set all values to 0 */
475 for (n=0; n < (int)uphR->data->length; n++) {
476 uphR->data->data[n] = 0.0;
477 }
478
479 /* Set one in every up_factor to the value of hR x USR */
480 for (n=0; n < (int)hR->data->length; n++) {
481 uphR->data->data[n * up_factor] = up_factor * hR->data->data[n];
482 }
483
484 return 0;
485}
486
487/*******************************************************************************/
488
490{
491 UINT4 n,m;
492
493 /* Set all values to 0 */
494 for (n=0; n < (UINT4)uphR->data->length; n++) {
495 uphR->data->data[n] = 0.0;
496 }
497
498 /* Set one in every up_factor to the value of hR x USR */
499 for (n=0; n < (UINT4)hR->data->length; n++)
500 {
501 REAL8 y_1=hR->data->data[n],y_2=0;
502
503 if(n < hR->data->length-1) y_2=hR->data->data[n+1];
504 if(n == hR->data->length-1) y_2=hR->data->data[n];
505
506 for (m=0; m < (UINT4)up_factor; m++)
507 {
508 uphR->data->data[n*up_factor+m] = y_1+m*(y_2-y_1)/up_factor;
509 }
510 }
511 return 0;
512}
513
514/*******************************************************************************/
515
517{
518
519 int n;
520
521 if (hR->data->length != ALPHAS->data->length)
522 {
523 fprintf(stderr,"Length of residual strin time series (%d), not the same as factors time series, (%d)\n"
524 ,hR->data->length, ALPHAS->data->length);
525 return 1;
526 }
527
528 for (n = 0; n < (int)hR->data->length; n++)
529 {
530 hR->data->data[n] /= ALPHAS->data->data[n];
531 }
532
533 return 0;
534}
535
536/*******************************************************************************/
537
539{
540
541static REAL4TimeSeries darm;
542static REAL4TimeSeries asq;
543static REAL4TimeSeries exc;
544
545CalFactors factors;
547
548REAL4Window *asqwin=NULL, *excwin=NULL, *darmwin=NULL; /* windows */
549INT4 k,m;
550
551REAL4 deltaT=input->DARM_ERR.deltaT, To=input->To;
552INT4 length = input->DARM_ERR.data->length;
553/*INT4 localtime = input->DARM_ERR.epoch.gpsSeconds;*/
554
557
558 /* Create local data vectors */
559 LALCreateVector(status->statusPtr,&asq.data,(UINT4)(To/input->AS_Q.deltaT +0.5));
561 LALCreateVector(status->statusPtr,&darm.data,(UINT4)(To/input->DARM.deltaT +0.5));
563 LALCreateVector(status->statusPtr,&exc.data,(UINT4)(To/input->EXC.deltaT +0.5));
565
566 /* assign time spacing for local time series */
567 asq.deltaT=input->AS_Q.deltaT;
568 darm.deltaT=input->DARM.deltaT;
569 exc.deltaT=input->EXC.deltaT;
570
571 /* windows for time domain channels */
572 /* asq */
573 asqwin = XLALCreateHannREAL4Window((UINT4)(To/input->AS_Q.deltaT +0.5));
574 ASSERT( asqwin != NULL, status, LAL_EXLAL, LAL_MSGEXLAL );
575
576 /* darm */
577 darmwin = XLALCreateHannREAL4Window((UINT4)(To/input->DARM.deltaT +0.5));
578 ASSERT( darmwin != NULL, status, LAL_EXLAL, LAL_MSGEXLAL );
579
580 /* exc */
581 excwin = XLALCreateHannREAL4Window((UINT4)(To/input->EXC.deltaT +0.5));
582 ASSERT( excwin != NULL, status, LAL_EXLAL, LAL_MSGEXLAL );
583
584 for(m=0; m < (UINT4)(deltaT*length) / To; m++)
585 {
586 /*int facterrflag=0;*/
587
588 /* assign and window the data */
589 for(k=0;k<(INT4)(To/asq.deltaT +0.5);k++)
590 {
591 asq.data->data[k] = input->AS_Q.data->data[m * (UINT4)(To/asq.deltaT) + k] * 2.0 * asqwin->data->data[k];
592 }
593 for(k=0;k<(INT4)(input->To/darm.deltaT +0.5);k++)
594 {
595 darm.data->data[k] = input->DARM.data->data[m *(UINT4)(To/darm.deltaT) + k] * 2.0 * darmwin->data->data[k];
596 }
597 for(k=0;k<(INT4)(input->To/exc.deltaT +0.5);k++)
598 {
599 exc.data->data[k] = input->EXC.data->data[m * (UINT4)(To/exc.deltaT) + k] * 2.0 * excwin->data->data[k];
600 }
601
602 /* set params to call LALComputeCalibrationFactors */
603 params.darmCtrl = &darm;
604 params.asQ = &asq;
605 params.exc = &exc;
606
607 params.lineFrequency = input->f;
608 params.openloop = input->Go;
609 params.digital = input->Do;
610 params.whitener = input->Wo;
611
612 LALComputeCalibrationFactors(status->statusPtr,&factors,&params);
614
615 if (input->gamma_fudgefactor != 0)
616 {
617 factors.alphabeta = creal(factors.alphabeta) / input->gamma_fudgefactor + I * cimag(factors.alphabeta);
618 }
619
620 output->alpha.data->data[m]= factors.alpha;
621 output->beta.data->data[m]= factors.beta;
622 output->alphabeta.data->data[m]= factors.alphabeta;
623
624 if(m == MAXALPHAS)
625 {
626 fprintf(stderr,"Too many values of the factors, maximum allowed is %d\n",MAXALPHAS);
627 RETURN(status);
628 }
629 }
630
631 /* Clean up */
632 LALDestroyVector(status->statusPtr,&darm.data);
634 LALDestroyVector(status->statusPtr,&exc.data);
636 LALDestroyVector(status->statusPtr,&asq.data);
638
640 XLALDestroyREAL4Window(darmwin);
642
644 RETURN (status);
645}
646
647
648
649/*******************************************************************************/
650
652{
653 int n,m;
654 REAL8 sum;
655 int Nfir,Ntseries;
656 REAL8 *x, *b;
657
658 x=tseries->data->data;
659 b=FIR->directCoef->data;
660
661 Nfir=FIR->directCoef->length;
662 Ntseries=tseries->data->length;
663
664 /* initialise values in FIR time series */
665 for (n = Ntseries-1; n >= Nfir-1; n--)
666 {
667 sum = 0;
668 for (m = Nfir-1; m >= 0; m--)
669 {
670 sum += b[m] * x[n-m];
671 }
672 x[n]=sum;
673 }
674 /* set to zero values at the start */
675 for (n = 0; n < (int)FIR->directCoef->length-1; n++)
676 {
677 x[n]=0;
678 }
679 return 0;
680}
681
682/*******************************************************************************/
683
685{
686
687 REAL8TimeSeries *tseriesFIR=NULL;
688 REAL8TimeSeries *tseriesDATA=NULL;
689 COMPLEX16FrequencySeries *vtilde=NULL, *vtildeFIR=NULL;
690 REAL8FFTPlan *fplan = NULL, *rplan = NULL;
691 int n;
692 int xlerr;
693
696
697 /* check that the time series is larger than the length of the filter */
698 if ( tseries->data->length < FIR->directCoef->length )
699 {
700 fprintf(stderr,"ERROR. tseries length (=%d) < filter length (=%d)",
701 tseries->data->length, FIR->directCoef->length);
702 ABORT(status,118,"Time series is smaller than filter length.");
703 }
704
705 /* create time series that will hold FIR filter (with room for zero padding) */
706 tseriesFIR = XLALCreateREAL8TimeSeries(tseries->name,
707 &tseries->epoch, 0.0, tseries->deltaT, &tseries->sampleUnits,
708 2*tseries->data->length);
709 if(!tseriesFIR)
710 ABORTXLAL( status );
711
712 /* create time series that will hold data (with room for zero padding) */
713 tseriesDATA = XLALCreateREAL8TimeSeries(tseries->name,
714 &tseries->epoch, 0.0, tseries->deltaT, &tseries->sampleUnits,
715 2*tseries->data->length);
716 if(!tseriesDATA)
717 ABORTXLAL( status );
718
719 /* initialise values in FIR time series */
720 for (n = 0; n < (int)tseriesDATA->data->length; n++)
721 {
722 tseriesFIR->data->data[n]=0.0;
723 tseriesDATA->data->data[n]=0.0;
724 }
725 /* set first few to values in FIR filter */
726 for (n = 0; n < (int)FIR->directCoef->length; n++)
727 {
728 tseriesFIR->data->data[n]=FIR->directCoef->data[n];
729 }
730
731 /* set first few to values in data series */
732 for (n = 0; n < (int)tseries->data->length; n++)
733 {
734 tseriesDATA->data->data[n]=tseries->data->data[n];
735 }
736
737 /* create frequency series that will hold FT's of both timne series */
738 vtilde = XLALCreateCOMPLEX16FrequencySeries(tseries->name , &tseries->epoch, 0.0,
739 1.0 / (tseries->data->length * tseries->deltaT),
740 &tseries->sampleUnits, tseriesDATA->data->length / 2 + 1);
741 if(!vtilde)
742 ABORTXLAL( status );
743 vtildeFIR = XLALCreateCOMPLEX16FrequencySeries(tseries->name , &tseries->epoch, 0.0,
744 1.0 / (tseries->data->length * tseries->deltaT),
745 &tseries->sampleUnits, tseriesDATA->data->length / 2 + 1);
746 if(!vtildeFIR)
747 ABORTXLAL( status );
748
749 /* make fft plans */
750 fplan = XLALCreateForwardREAL8FFTPlan(tseriesDATA->data->length, 0 );
751 if (fplan == NULL)
753 rplan = XLALCreateReverseREAL8FFTPlan(tseriesDATA->data->length, 0 );
754 if (rplan == NULL)
756
757 /* fft both series */
758 xlerr=XLALREAL8TimeFreqFFT(vtilde, tseriesDATA, fplan);
759 if( xlerr < 0 )
760 {
761 fprintf(stderr,"Failed creating FT of time series. Errorcode: %d\n",xlerr);
763 RETURN(status);
764 }
765 xlerr=XLALREAL8TimeFreqFFT(vtildeFIR, tseriesFIR, fplan);
766 if( xlerr < 0 )
767 {
768 fprintf(stderr,"Failed creating FT of FIR filter time series. Errorcode: %d\n",xlerr);
770 RETURN(status);
771 }
772
773 /* multiply both FT's */
774 for (n = 0; n < (int)vtilde->data->length; n++)
775 {
776 vtilde->data->data[n] *= vtildeFIR->data->data[n];
777 }
778
779 /* reverse FFT into original time series */
780 xlerr=XLALREAL8FreqTimeFFT(tseriesDATA, vtilde, rplan);
781 if( xlerr < 0 )
782 {
783 fprintf(stderr,"Failed creating IFT of FIR and time series. Errorcode: %d\n",xlerr);
785 RETURN(status);
786 }
787
788 for (n = 0; n < (int)tseries->data->length; n++)
789 {
790 tseries->data->data[n] = tseriesDATA->data->data[n]/tseries->deltaT;
791 }
792
793 /* Destroy everything */
796
799 XLALDestroyREAL8TimeSeries(tseriesFIR);
800 XLALDestroyREAL8TimeSeries(tseriesDATA);
801
803 RETURN( status );
804
805}
806
807
808
809/*
810 * Check if there are any nans or infs in the input data.
811 */
813{
814 UINT4 p;
815
816 /* Check if there are nans or infs in DARM_ERR */
817 for (p=0; p < input->DARM_ERR.data->length; p++) {
818 REAL4 x = input->DARM_ERR.data->data[p];
819 if (isnan(x) || isinf(x)) {
820 fprintf(stderr, "ERROR: bad DARM_ERR\n");
821 ABORT(status, 1, "Bad DARM_ERR");
822 }
823 }
824
825 /* Same thing for DARM_CTRL if we use it */
826 if (input->darmctrl) {
827 for (p=0; p < input->DARM.data->length; p++) {
828 REAL4 x = input->DARM.data->data[p];
829 if (isnan(x) || isinf(x)) {
830 fprintf(stderr, "ERROR: bad DARM_CTRL\n");
831 ABORT(status, 2, "Bad DARM_CTRL");
832 }
833 }
834 }
835}
836
837
838
839
841{
842 memset(output->h.data->data, 0, output->h.data->length * sizeof(REAL8));
843 memset(output->hR.data->data, 0, output->hR.data->length * sizeof(REAL8));
844 memset(output->hC.data->data, 0, output->hC.data->length * sizeof(REAL8));
845 memset(output->alpha.data->data, 0, output->alpha.data->length * sizeof(COMPLEX16));
846 memset(output->beta.data->data, 0, output->beta.data->length * sizeof(COMPLEX16));
847 memset(output->alphabeta.data->data, 0, output->alphabeta.data->length * sizeof(COMPLEX16));
848}
849
850
851#if 0
852/*
853 * Put DARM_ERR and DARM_CTRL to 0 if the detector is not UP. That
854 * way, we remove the huge transients with the new DC readout scheme.
855 *
856 * Also, even if the detector is UP, if DARM_ERR is way too big (~> 1)
857 * or its derivative (~> 1e-3), assume we have a glitch.
858 */
859static void remove_transients(StrainIn *input)
860{
861 int i, j; /* counters */
862 float sum_x, sum_y;
863 int light; /* is there light in the arms? */
864 int up; /* state vector up bit */
865
866 int nsecs; /* number of seconds of data */
867 int r_sv, r_light, r_darm; /* samples per second */
868
869 const double DARM_ERR_THRESHOLD = 1e0;
870 int derr_small; /* is DARM_ERR believably small? */
871 const double DERIV_THRESHOLD = 1e-3;
872 int deriv_small; /* is the derivative of DARM_ERR believably small? */
873
874 nsecs = (int) (input->DARM_ERR.data->length * input->DARM_ERR.deltaT);
875
876 r_sv = input->StateVector.data->length / nsecs; /* # of IFO-SV_STATE_VECTOR per second */
877 r_light = input->LAX.data->length / nsecs; /* # of LSC-LA_PTRX_NORM per second */
878 r_darm = input->DARM_ERR.data->length / nsecs; /* # of DARM_ERR per second */
879
880 /* For each second, check the conditions and put DARM_* to 0 if not met */
881 for (i = 0; i < nsecs; i++) {
882 /*
883 * Is the detector UP? (state vector UP during the whole
884 * second, and light in the arms)
885 */
886
887 /* light */
888 sum_x = 0;
889 sum_y = 0;
890 for (j = 0; j < r_light; j++) {
891 sum_x += input->LAX.data->data[i*r_light + j];
892 sum_y += input->LAY.data->data[i*r_light + j];
893 }
894
895 light = (sum_x/r_light > 100 && sum_y/r_light > 100);
896 /* "is the mean higher than 100 for both arms?" */
897
898 /* state vector up */
899 up = 1;
900
901 for (j = 0; j < r_sv; j++) {
902 /* convert from float to int, and take the third rightmost bit */
903 int s = (int) input->StateVector.data->data[i*r_sv + j];
904 if ((s & (1 << 2)) == 0) up = 0;
905 }
906
907 up = up && light; /* this is the "up" definition of the DQ vector */
908
909 /* DARM_ERR below threshold */
910 REAL4 *derr = input->DARM_ERR.data->data; /* for short notation */
911 derr_small = 1;
912 for (j = 0; j < r_darm; j++)
913 if (fabs(derr[i*r_darm + j]) > DARM_ERR_THRESHOLD)
914 derr_small = 0;
915
916 /* DARM_ERR derivative below threshold */
917 deriv_small = 1;
918 for (j = 0; j < r_darm-1; j++)
919 if (fabs(derr[i*r_darm + j+1] - derr[i*r_darm + j]) > DERIV_THRESHOLD)
920 deriv_small = 0;
921
922 /*
923 * Scare the users.
924 */
925 if (up && !(derr_small && deriv_small))
926 fprintf(stderr, "WARNING: glitch found by non-conventional methods. "
927 "Zeroing presumed bad data so it doesn't affect the rest of the frame.\n");
928
929 /*
930 * Put DARM_ERR and DARM_CTRL to 0 if we don't meet the conditions.
931 */
932 if (! (up && derr_small && deriv_small) ) {
933 for (j = 0; j < r_darm; j++) {
934 input->DARM_ERR.data->data[i*r_darm + j] = 0.0;
935 input->DARM.data->data[i*r_darm + j] = 0.0;
936 }
937 }
938 }
939}
940#endif
void LALComputeCalibrationFactors(LALStatus *status, CalFactors *output, UpdateFactorsParams *input)
#define N_FIR_HP
Definition: ComputeStrain.c:50
void LALComputeStrain(LALStatus *status, StrainOut *output, StrainIn *input)
Definition: ComputeStrain.c:63
#define MAXALPHAS
Definition: ComputeStrain.c:41
static void set_output_to_zero(StrainOut *output)
static void check_nans_infs(LALStatus *status, StrainIn *input)
#define fhigh_FIRLP_ALPHAS
Definition: ComputeStrain.c:44
int XLALUpsample(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
void LALMakeFIRLP(LALStatus *status, REAL8IIRFilter *LPFIR, int USF)
void LALGetFactors(LALStatus *status, StrainOut *output, StrainIn *input)
#define N_FIR_LP
Definition: ComputeStrain.c:46
int XLALUpsampleLinear(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
void LALMakeFIRLPALPHAS(LALStatus *status, REAL8IIRFilter *LPFIR)
#define fhigh_FIRHP
Definition: ComputeStrain.c:51
int XLALDivideTimeSeries(REAL8TimeSeries *hR, REAL8TimeSeries *ALPHAS)
void LALFFTFIRFilter(LALStatus *status, REAL8TimeSeries *tseries, REAL8IIRFilter *FIR)
#define N_FIR_LP_ALPHAS
Definition: ComputeStrain.c:43
void LALMakeFIRHP(LALStatus *status, REAL8IIRFilter *HPFIR)
#define fhigh_FIRLP
Definition: ComputeStrain.c:48
int XLALFIRFilter(REAL8TimeSeries *tseries, REAL8IIRFilter *FIR)
#define ABORT(statusptr, code, mesg)
#define CHECKSTATUSPTR(statusptr)
#define LAL_EXLAL
#define LAL_MSGEXLAL
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define ABORTXLAL(sp)
#define fprintf
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_PI
Archimedes's constant, pi.
Definition: LALConstants.h:179
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
@ LALNumUnits
The number of units.
Definition: LALDatatypes.h:480
static const INT4 r
Definition: Random.c:82
static const INT4 m
Definition: Random.c:80
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
Destroys a REAL8FFTPlan.
Definition: CudaRealFFT.c:454
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
Returns a new REAL8FFTPlan for a reverse transform.
Definition: CudaRealFFT.c:444
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
Returns a new REAL8FFTPlan for a forward transform.
Definition: CudaRealFFT.c:434
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *time, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:117
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *time, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:153
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void LALDestroyVector(LALStatus *, REAL4Vector **)
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALCreateVector(LALStatus *, REAL4Vector **, UINT4)
void XLALDestroyREAL4Window(REAL4Window *window)
Definition: Window.c:757
REAL4Window * XLALCreateHannREAL4Window(UINT4 length)
Definition: Window.c:691
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:909
COMPLEX16Sequence * data
Definition: LALDatatypes.h:915
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:176
COMPLEX16 * data
Pointer to the data array.
Definition: LALDatatypes.h:177
UNDOCUMENTED.
Definition: Calibration.h:82
COMPLEX16 alphabeta
Definition: Calibration.h:84
COMPLEX16 alpha
Definition: Calibration.h:83
COMPLEX16 beta
Definition: Calibration.h:85
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
REAL4Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:576
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:573
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Structure for storing REAL4 window function data, providing storage for a sequence of samples as well...
Definition: Window.h:243
REAL4Sequence * data
The window function samples.
Definition: Window.h:244
This structure stores the direct and recursive REAL8 filter coefficients, as well as the history of t...
Definition: IIRFilter.h:168
REAL8Vector * history
The previous values of w.
Definition: IIRFilter.h:173
REAL8Vector * recursCoef
The recursive filter coefficients.
Definition: IIRFilter.h:172
REAL8Vector * directCoef
The direct filter coefficients.
Definition: IIRFilter.h:171
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:580
REAL8Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:586
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:585
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:583
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:582
CHAR name[LALNameLength]
The name of the time series.
Definition: LALDatatypes.h:581
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
UNDOCUMENTED.
Definition: Calibration.h:183
REAL4TimeSeries EXC
timeseries containing the excitation
Definition: Calibration.h:187
COMPLEX16 Do
digital filter at cal line frequency
Definition: Calibration.h:191
REAL8IIRFilter * Cinv
Filters for inverse of sensing function.
Definition: Calibration.h:198
INT4 usefactors
UNDOCUMENTED.
Definition: Calibration.h:206
REAL8IIRFilter * D
Filters for analog actuation function.
Definition: Calibration.h:202
INT4 delta
UNDOCUMENTED.
Definition: Calibration.h:205
REAL8 f
calibration line frequency
Definition: Calibration.h:194
INT4 fftconv
UNDOCUMENTED.
Definition: Calibration.h:208
INT4 outalphas
UNDOCUMENTED.
Definition: Calibration.h:209
REAL8IIRFilter * A
Filters for analog actuation function.
Definition: Calibration.h:201
REAL8IIRFilter * AW
Filters for analog actuation function.
Definition: Calibration.h:203
REAL4TimeSeries AS_Q
timeseries containing ASQ
Definition: Calibration.h:184
REAL4TimeSeries StateVector
timeseries containing the State Vector (IFO-SV_STATE_VECTOR)
Definition: Calibration.h:188
REAL4TimeSeries DARM
timeseries containing DARM_CTRL
Definition: Calibration.h:186
INT4 CinvUSF
Upsampling factor for sensing function.
Definition: Calibration.h:199
COMPLEX16 Wo
Whitening filter at cal line frequency.
Definition: Calibration.h:193
INT4 darmctrl
UNDOCUMENTED.
Definition: Calibration.h:210
COMPLEX16 Go
OLG at cal line frequency.
Definition: Calibration.h:192
INT4 CinvDelay
Overall inverse sensing function delay.
Definition: Calibration.h:200
REAL4TimeSeries LAY
timeseries containing the Light-in-Y-arm (LSC-LA_PTRY_NORM)
Definition: Calibration.h:190
REAL8 gamma_fudgefactor
UNDOCUMENTED.
Definition: Calibration.h:204
REAL4 To
factors integration time
Definition: Calibration.h:195
REAL4TimeSeries LAX
timeseries containing the Light-in-X-arm (LSC-LA_PTRX_NORM)
Definition: Calibration.h:189
REAL4TimeSeries DARM_ERR
timeseries containing DARM_ERR
Definition: Calibration.h:185
UNDOCUMENTED.
Definition: Calibration.h:171
UNDOCUMENTED.
Definition: Calibration.h:96
REAL4TimeSeries * darmCtrl
Definition: Calibration.h:101
REAL4TimeSeries * exc
Definition: Calibration.h:103
COMPLEX16 openloop
Definition: Calibration.h:98
REAL4TimeSeries * asQ
Definition: Calibration.h:102
void output(int gps_sec, int output_type)
Definition: tconvert.c:440