LAL  7.5.0.1-08ee4f4
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. */
56 static void set_output_to_zero(StrainOut *output);
57 static void check_nans_infs(LALStatus *status, StrainIn *input);
58 #if 0
59 static void remove_transients(StrainIn *input);
60 #endif
61 
62 
66  StrainIn *input
67  )
68 {
69 /* Inverse sensing, servo, analog actuation, digital x
70 actuation digital y actuation */
71 static REAL8TimeSeries ALPHAS,upALPHAS;
72 int p;
73 REAL8IIRFilter HPFIR;
74 REAL8IIRFilter 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];
429  REAL8 fN=fhigh_FIRHP;
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 
470 int 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 
489 int XLALUpsampleLinear(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
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 
541 static REAL4TimeSeries darm;
542 static REAL4TimeSeries asq;
543 static REAL4TimeSeries exc;
544 
545 CalFactors factors;
546 UpdateFactorsParams params;
547 
548 REAL4Window *asqwin=NULL, *excwin=NULL, *darmwin=NULL; /* windows */
549 INT4 k,m;
550 
551 REAL4 deltaT=input->DARM_ERR.deltaT, To=input->To;
552 INT4 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 
639  XLALDestroyREAL4Window(asqwin);
640  XLALDestroyREAL4Window(darmwin);
641  XLALDestroyREAL4Window(excwin);
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)
752  ABORTXLAL(status);
753  rplan = XLALCreateReverseREAL8FFTPlan(tseriesDATA->data->length, 0 );
754  if (rplan == NULL)
755  ABORTXLAL(status);
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  */
859 static 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
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
void LALDestroyVector(LALStatus *, REAL4Vector **)
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALCreateVector(LALStatus *, REAL4Vector **, UINT4)
REAL4Window * XLALCreateHannREAL4Window(UINT4 length)
Definition: Window.c:691
void XLALDestroyREAL4Window(REAL4Window *window)
Definition: Window.c:757
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