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
ComputeStrainDMT.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 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 .9
48
49#define N_FIR_HP 2000
50#define fhigh_FIRHP 0.00244140625
51
55 StrainIn *input
56 )
57{
58/* Inverse sensing, servo, analog actuation, digital x
59actuation digital y actuation */
60static REAL8TimeSeries uphR,hCX,hCY,ALPHAS,upALPHAS;
61int p, NWingsR,NWingsC;
62REAL8IIRFilter LPFIR;
63REAL8IIRFilter HPFIR;
64REAL8IIRFilter ALPHASLPFIR;
65REAL8IIRFilter *CinvWings=NULL, *DWings=NULL, *AAWings=NULL, *AXWings=NULL, *AYWings=NULL;
66
67
70
71 LALGetFactors(status->statusPtr, output, input);
73
74 LALMakeFIRLP(status->statusPtr, &LPFIR, input->CinvUSF);
76
77 LALMakeFIRHP(status->statusPtr, &HPFIR);
79
80 /* Create vectors that will hold the residual, control and net strain signals */
81 LALDCreateVector(status->statusPtr,&hCX.data,input->AS_Q.data->length);
83 LALDCreateVector(status->statusPtr,&hCY.data,input->AS_Q.data->length);
85
86 NWingsR = (int)(input->wings/input->AS_Q.deltaT + 0.5) * input->CinvUSF;
87 NWingsC = (int)(input->wings/input->AS_Q.deltaT + 0.5);
88
89 /* copy AS_Q input into residual strain as double */
90 for (p=0; p<(int)output->hR.data->length; p++)
91 {
92 output->hR.data->data[p]=input->DARM_ERR.data->data[p];
93 }
94
95 /* copy DARM_ERR input into control strain as double */
96 for (p=0; p<(int)output->hC.data->length; p++)
97 {
98 output->hC.data->data[p]=input->DARM_ERR.data->data[p];
99 }
100
101 /* unit impulse */
102 if (input->delta)
103 {
104 for (p=0; p<(int)output->hR.data->length; p++)
105 {
106 output->hR.data->data[p]=0;
107 }
108 output->hR.data->data[output->hC.data->length/2]=1.0;
109 }
110
111 /* unit impulse */
112 if (input->delta)
113 {
114 for (p=0; p<(int)output->hC.data->length; p++)
115 {
116 output->hC.data->data[p]=0;
117 }
118 output->hC.data->data[output->hC.data->length/2]=1.0;
119 }
120
121 /* ---------- Compute Residual Strain -------------*/
122
123 LALDCreateVector(status->statusPtr,&uphR.data,input->CinvUSF*input->AS_Q.data->length);
125 uphR.deltaT=input->AS_Q.deltaT/input->CinvUSF;
126
127 /* then we upsample (and smooth it with a low pass filter) */
128 if(XLALUpsample(&uphR, &(output->hR), input->CinvUSF))
129 {
130 ABORT(status,117,"Broke upsampling hR");
131 }
132
133 /* apply delay (actually an advance) */
134 for (p=0; p<(int)uphR.data->length+input->CinvDelay; p++){
135 uphR.data->data[p]=uphR.data->data[p-input->CinvDelay];
136 }
137
138 /* An odd filter with N points introduces an (N-1)/2 delay */
139 /* apply advance to compensate for FIR delay */
140 for (p=0; p<(int)uphR.data->length-(2*N_FIR_LP); p++){
141 uphR.data->data[p]=uphR.data->data[p+(2*N_FIR_LP)];
142 }
143 /* Low pass filter twice to smooth time series */
144 LALIIRFilterREAL8Vector(status->statusPtr,uphR.data,&(LPFIR));
146 LALIIRFilterREAL8Vector(status->statusPtr,uphR.data,&(LPFIR));
148
149 /* ===================== */
150 /* CAREFUL FILTERING: FILTER UP TO WINGS, THEN COPY FILTERS THEN CONTINUE UNTIL END */
151 /* filter only up until the wings */
152 for(p = 0; p < input->NCinv; p++){
153 int k;
154 for(k = NWingsR/2; k < (int)uphR.data->length-3*NWingsR/2; k++){
155 uphR.data->data[k]=LALDIIRFilter(uphR.data->data[k], &(input->Cinv[p]));
156 }
157 }
158 /* Here what I need to record filter histories */
159 LALCopyFilter(status->statusPtr, &CinvWings, input->Cinv, input->NCinv);
161 /* then we filter wings as well */
162 for(p = 0; p < input->NCinv; p++){
163 int k;
164 for(k = uphR.data->length-3*NWingsR/2; k < (int)uphR.data->length-NWingsR/2; k++){
165 uphR.data->data[k]=LALDIIRFilter(uphR.data->data[k], &CinvWings[p]);
166 }
167 }
168 /* Then we need to destroy the filter */
169 LALFreeFilter(status->statusPtr,CinvWings,input->NCinv);
171 /* ===================== */
172
173 /* apply advance to compensate for Low Pass FIR delay */
174 for (p=0; p<(int)uphR.data->length-(2*N_FIR_LP); p++){
175 uphR.data->data[p]=uphR.data->data[p+(2*N_FIR_LP)];
176 }
177 /* Low pass filter twice to smooth time series */
178 LALIIRFilterREAL8Vector(status->statusPtr,uphR.data,&(LPFIR));
180 LALIIRFilterREAL8Vector(status->statusPtr,uphR.data,&(LPFIR));
182
183 /* then we downsample and voila' */
184 for (p=0; p<(int)output->hR.data->length; p++) {
185 output->hR.data->data[p]=uphR.data->data[p*input->CinvUSF];
186 }
187
188 LALDDestroyVector(status->statusPtr,&uphR.data);
190
191 /* Create time series that hold alpha time series and upsampled alpha time-series */
192 LALDCreateVector(status->statusPtr,&ALPHAS.data,output->alpha.data->length);
194 LALDCreateVector(status->statusPtr,&upALPHAS.data,input->AS_Q.data->length);
196 upALPHAS.deltaT=input->AS_Q.deltaT;
197
198 /* copy factors into time series */
199 for (p=0; p<(int)ALPHAS.data->length; p++)
200 {
201 ALPHAS.data->data[p]=creal(output->alphabeta.data->data[p]);
202 }
203
204 /* upsample using a linear interpolation */
205 if(XLALUpsampleLinear(&upALPHAS, &ALPHAS, (int) (output->alphabeta.deltaT/input->AS_Q.deltaT+0.5)))
206 {
207 ABORT(status,117,"Broke upsampling Alphas");
208 }
209
210 /* Generate alphas LP filter to smooth linearly interpolated factors time series */
211 LALMakeFIRLPALPHAS(status->statusPtr, &ALPHASLPFIR);
213
214 /* Note that I do not compensate for delay
215 if factors are computed every second then everything is fine */
216 if (input->fftconv)
217 {
218 LALFFTFIRFilter(status->statusPtr,&upALPHAS,&ALPHASLPFIR);
220 }else{
221 LALIIRFilterREAL8Vector(status->statusPtr,upALPHAS.data,&(ALPHASLPFIR));
223 }
224
225 /* finally we divide by alpha*beta */
226 if (input->usefactors)
227 {
228 if(XLALDivideTimeSeries(&(output->hR), &upALPHAS))
229 {
230 ABORT(status,116,"Broke at hR/alpha");
231 }
232 }
233
234 if (input->outalphas)
235 {
236 /* set output to alphas */
237 for (p=0; p<(int)output->hR.data->length; p++) {
238 output->hR.data->data[p]=upALPHAS.data->data[p];
239 }
240 }
241
242 /* destroy low and high pass filters */
243 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.directCoef));
245 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.recursCoef));
247 LALDDestroyVector(status->statusPtr,&(ALPHASLPFIR.history));
249
250 /* destroy both alphas time series */
251 LALDDestroyVector(status->statusPtr,&upALPHAS.data);
253 LALDDestroyVector(status->statusPtr,&ALPHAS.data);
255
256 /* ---------- Compute Control Strain -------------*/
257
258 /* first implement the time delay filter; start at end to avoid overwriting */
259 for (p = (int)output->hC.data->length-1; p >= input->AADelay; p--){
260 output->hC.data->data[p]=output->hC.data->data[p-input->AADelay];
261 }
262
263 /* then apply advance to compensate for FIR delay */
264 for (p=0; p<(int)output->hC.data->length-(2*N_FIR_HP); p++){
265 output->hC.data->data[p]=output->hC.data->data[p+(2*N_FIR_HP)];
266 }
267 /* then high pass filter DARM_ERR */
268 if (input->fftconv)
269 {
270 LALFFTFIRFilter(status->statusPtr,&(output->hC),&(HPFIR));
272 LALFFTFIRFilter(status->statusPtr,&(output->hC),&(HPFIR));
274 }else{
275 LALIIRFilterREAL8Vector(status->statusPtr,output->hC.data,&(HPFIR));
277 LALIIRFilterREAL8Vector(status->statusPtr,output->hC.data,&(HPFIR));
279 }
280
281 /* Filter through digital servo */
282 /* ===================== */
283 /* CAREFUL FILTERING: FILTER UP TO WINGS, THEN COPY FILTERS THEN CONTINUE UNTIL END*/
284 /* we filter but only up until the wings */
285 for(p = 0; p < input->ND; p++){
286 int k;
287 for(k = NWingsC/2; k < (int)output->hC.data->length-3*NWingsC/2; k++){
288 output->hC.data->data[k]=LALDIIRFilter(output->hC.data->data[k], &(input->D[p]));
289 }
290 }
291 /* Here what I need to record filter histories */
292 LALCopyFilter(status->statusPtr, &DWings, input->D, input->ND);
294 /* then we filter wings as well */
295 for(p = 0; p < input->ND; p++){
296 int k;
297 for(k = output->hC.data->length-3*NWingsC/2; k < (int)output->hC.data->length-NWingsC/2; k++){
298 output->hC.data->data[k]=LALDIIRFilter(output->hC.data->data[k], &DWings[p]);
299 }
300 }
301 /* Then we need to destroy the filter */
302 LALFreeFilter(status->statusPtr,DWings,input->ND);
304 /* ===================== */
305
306 /* At this point I have something very similar to darm_ctrl in hC */
307 /* add the calibration lines */
308 if (!input->delta && (input->DARM_ERR.deltaT == input->EXC.deltaT))
309 {
310 int k;
311 for(k = 0; k < (int)output->hC.data->length; k++){
312 output->hC.data->data[k] += input->EXC.data->data[k];
313 }
314 }
315 else
316 {
317 fprintf(stdout, "Warning: Not adding calibration lines to control signal.\n");
318 }
319
320
321 /* Filter through analog actuation */
322 /* ===================== */
323 /* CAREFUL FILTERING: FILTER UP TO WINGS, THEN COPY FILTERS THEN CONTINUE UNTIL END */
324 /* we filter but only up until the wings */
325 for(p = 0; p < input->NAA; p++){
326 int k;
327 for(k = NWingsC/2; k < (int)output->hC.data->length-3*NWingsC/2; k++){
328 output->hC.data->data[k]=LALDIIRFilter(output->hC.data->data[k], &(input->AA[p]));
329 }
330 }
331 /* Here what I need to record filter histories */
332 LALCopyFilter(status->statusPtr, &AAWings, input->AA, input->NAA);
334 /* then we filter wings as well */
335 for(p = 0; p < input->NAA; p++){
336 int k;
337 for(k = output->hC.data->length-3*NWingsC/2; k < (int)output->hC.data->length-NWingsC/2; k++){
338 output->hC.data->data[k]=LALDIIRFilter(output->hC.data->data[k], &AAWings[p]);
339 }
340 }
341 /* Then we need to destroy the filter */
342 LALFreeFilter(status->statusPtr,AAWings,input->NAA);
344 /* ===================== */
345
346 /* Copy data into x and y time series for parallel filtering */
347 for (p=0; p < (int)output->hC.data->length; p++){
348 hCX.data->data[p] = output->hC.data->data[p];
349 hCY.data->data[p] = output->hC.data->data[p];
350 }
351
352 /* Filter x-arm */
353 /* ===================== */
354 /* CAREFUL FILTERING: FILTER UP TO WINGS, THEN COPY FILTERS THEN CONTINUE UNTIL END */
355 /* we filter only up until the wings */
356 for(p = 0; p < input->NAX; p++){
357 int k;
358 for(k = NWingsC/2; k < (int)hCX.data->length-3*NWingsC/2; k++){
359 hCX.data->data[k]=LALDIIRFilter(hCX.data->data[k], &(input->AX[p]));
360 }
361 }
362 /* Here what I need to record filter histories */
363 LALCopyFilter(status->statusPtr, &AXWings, input->AX, input->NAX);
365 /* then we filter wings as well */
366 for(p = 0; p < input->NAX; p++){
367 int k;
368 for(k = hCX.data->length-3*NWingsC/2; k < (int)hCX.data->length-NWingsC/2; k++){
369 hCX.data->data[k]=LALDIIRFilter(hCX.data->data[k], &AXWings[p]);
370 }
371 }
372 /* Then we need to destroy the filter */
373 LALFreeFilter(status->statusPtr,AXWings,input->NAX);
375 /* ===================== */
376
377
378 /* Filter y-arm */
379 /* ===================== */
380 /* CAREFUL FILTERING: FILTER UP TO WINGS, THEN COPY FILTERS THEN CONTINUE UNTIL END */
381 /* we filter only up until the wings */
382 for(p = 0; p < input->NAY; p++){
383 int k;
384 for(k = NWingsC/2; k < (int)hCY.data->length-3*NWingsC/2; k++){
385 hCY.data->data[k]=LALDIIRFilter(hCY.data->data[k], &(input->AY[p]));
386 }
387 }
388 /* Here what I need to record filter histories */
389 LALCopyFilter(status->statusPtr, &AYWings, input->AY, input->NAY);
391 /* then we filter wings as well */
392 for(p = 0; p < input->NAY; p++){
393 int k;
394 for(k = hCY.data->length-3*NWingsC/2; k < (int)hCY.data->length-NWingsC/2; k++){
395 hCY.data->data[k]=LALDIIRFilter(hCY.data->data[k], &AYWings[p]);
396 }
397 }
398 /* Then we need to destroy the filter */
399 LALFreeFilter(status->statusPtr,AYWings,input->NAY);
401 /* ===================== */
402
403 /* add them together to make the total control signal */
404 for (p=0; p < (INT4)output-> h.data->length; p++) {
405 output->hC.data->data[p]=(hCX.data->data[p]-hCY.data->data[p]);
406 }
407
408
409 /* ---------- Compute Net Strain -------------*/
410
411 /* add x-arm and y-arm and voila' */
412 for (p=0; p< (int)output->h.data->length; p++){
413 output->h.data->data[p] = output->hC.data->data[p]+output->hR.data->data[p];
414 }
415
416 /* ------------------------------------------*/
417
418 /* destroy vectors that hold the data */
419 LALDDestroyVector(status->statusPtr,&hCX.data);
421 LALDDestroyVector(status->statusPtr,&hCY.data);
423
424 /* destroy low and high pass filters */
425 LALDDestroyVector(status->statusPtr,&(LPFIR.directCoef));
427 LALDDestroyVector(status->statusPtr,&(LPFIR.recursCoef));
429 LALDDestroyVector(status->statusPtr,&(LPFIR.history));
431 LALDDestroyVector(status->statusPtr,&(HPFIR.directCoef));
433 LALDDestroyVector(status->statusPtr,&(HPFIR.recursCoef));
435 LALDDestroyVector(status->statusPtr,&(HPFIR.history));
437
439 RETURN( status );
440
441}
442
443
444/*******************************************************************************/
446{
447 int n;
450
451 for(n=0;n<ORDER;n++){
452 LALDDestroyVector(status->statusPtr,&(F2[n].directCoef));
454 LALDDestroyVector(status->statusPtr, &(F2[n].recursCoef));
456 LALDDestroyVector(status->statusPtr,&(F2[n].history));
458 }
459 LALFree(F2);
460
462 RETURN( status );
463}
464
465/*******************************************************************************/
466
468{
469 REAL8IIRFilter *F2Array;
470 int n;
473
474 /* Allocate inverse sensing funtion filters */
475 *F2=F2Array=(REAL8IIRFilter *)LALMalloc(sizeof(REAL8IIRFilter) * ORDER);
476
477 for(n = 0; n < ORDER; n++)
478 {
479 int l;
480 F2Array[n].directCoef=NULL;
481 F2Array[n].recursCoef=NULL;
482 F2Array[n].history=NULL;
483
484 LALDCreateVector(status->statusPtr,&(F2Array[n].directCoef),F1[n].directCoef->length);
486 LALDCreateVector(status->statusPtr,&(F2Array[n].recursCoef),F1[n].recursCoef->length);
488 LALDCreateVector(status->statusPtr,&(F2Array[n].history),F1[n].history->length);
490
491 for(l=0;l<(int)F1[n].directCoef->length;l++)
492 F2Array[n].directCoef->data[l] = F1[n].directCoef->data[l];
493 for(l=0;l<(int)F1[n].recursCoef->length;l++)
494 F2Array[n].recursCoef->data[l] = F1[n].recursCoef->data[l];
495 for(l=0;l<(int)F1[n].history->length;l++)
496 F2Array[n].history->data[l] = F1[n].history->data[l];
497 }
498
500 RETURN( status );
501}
void LALMakeFIRLP(LALStatus *status, REAL8IIRFilter *G, int USF)
void LALMakeFIRHP(LALStatus *status, REAL8IIRFilter *G)
int XLALUpsample(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
void LALGetFactors(LALStatus *status, StrainOut *output, StrainIn *input)
void LALMakeFIRLPALPHAS(LALStatus *status, REAL8IIRFilter *G)
int XLALUpsampleLinear(REAL8TimeSeries *uphR, REAL8TimeSeries *hR, int up_factor)
int XLALDivideTimeSeries(REAL8TimeSeries *hR, REAL8TimeSeries *ALPHAS)
void LALFFTFIRFilter(LALStatus *status, REAL8TimeSeries *tseries, REAL8IIRFilter *FIR)
#define N_FIR_HP
#define N_FIR_LP
void LALCopyFilter(LALStatus *status, REAL8IIRFilter **F2, REAL8IIRFilter *F1, int ORDER)
void LALFreeFilter(LALStatus *status, REAL8IIRFilter *F2, int ORDER)
void LALComputeStrainDMT(LALStatus *status, StrainOut *output, StrainIn *input)
#define LALDIIRFilter(x, f)
Definition: IIRFilter.h:216
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
#define ABORT(statusptr, code, mesg)
#define CHECKSTATUSPTR(statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define fprintf
void LALIIRFilterREAL8Vector(LALStatus *status, REAL8Vector *vector, REAL8IIRFilter *filter)
WARNING: THIS FUNCTION IS OBSOLETE.
int32_t INT4
Four-byte signed integer.
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
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
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
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:583
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
INT4 NAA
UNDOCUMENTED.
Definition: Calibration.h:218
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
INT4 fftconv
UNDOCUMENTED.
Definition: Calibration.h:208
INT4 outalphas
UNDOCUMENTED.
Definition: Calibration.h:209
INT4 NAX
UNDOCUMENTED.
Definition: Calibration.h:219
REAL8IIRFilter * AY
Digital filters for y arm actuation function.
Definition: Calibration.h:215
REAL4TimeSeries AS_Q
timeseries containing ASQ
Definition: Calibration.h:184
INT4 AADelay
Overall analog actuation function delay.
Definition: Calibration.h:213
INT4 NAY
UNDOCUMENTED.
Definition: Calibration.h:220
INT4 wings
size of wings in seconds
Definition: Calibration.h:207
INT4 NCinv
Numbers of filters of each type.
Definition: Calibration.h:216
INT4 CinvUSF
Upsampling factor for sensing function.
Definition: Calibration.h:199
REAL8IIRFilter * AX
Digital filters for x arm actuation function.
Definition: Calibration.h:214
REAL8IIRFilter * AA
Filters for analog actuation function.
Definition: Calibration.h:212
INT4 CinvDelay
Overall inverse sensing function delay.
Definition: Calibration.h:200
INT4 ND
UNDOCUMENTED.
Definition: Calibration.h:217
REAL4TimeSeries DARM_ERR
timeseries containing DARM_ERR
Definition: Calibration.h:185
UNDOCUMENTED.
Definition: Calibration.h:171
void output(int gps_sec, int output_type)
Definition: tconvert.c:440