LALApps 10.1.0.1-eeff03c
series.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Duncan Brown, Stephen Fairhurst
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 <math.h>
21#include <ctype.h>
22#include <stdio.h>
23#include <stdlib.h>
24
25#include <FrameL.h>
26
27#include "series.h"
28
29double epoch_diff( const LIGOTimeGPS *t2, const LIGOTimeGPS *t1 )
30{
31 long long dt;
32 dt = 1000000000LL * (long long) t2->gpsSeconds;
33 dt += (long long) t2->gpsNanoSeconds;
34 dt -= 1000000000LL * (long long) t1->gpsSeconds;
35 dt -= (long long) t1->gpsNanoSeconds;
36 return 1e-9 * (double)dt;
37}
38
39void epoch_add( LIGOTimeGPS *t1, LIGOTimeGPS *t0, double dt )
40{
41 long long t;
42 t = 1000000000LL * (long long) t0->gpsSeconds;
43 t += (long long) t0->gpsNanoSeconds;
44 t += (long long)( 1e9 * dt );
45 t1->gpsSeconds = t / 1000000000LL;
46 t1->gpsNanoSeconds = t % 1000000000LL;
47 return;
48}
49
50int write_ilwd( const char *fname, const struct series *ser )
51{
52 size_t i;
53 FILE *fp;
54 if ( ser->type != FR_VECT_4R && ser->type != FR_VECT_8C )
55 {
56 fprintf( stderr, "unknown data type in series: %d\nmust be 4R or 8C\n",
57 ser->type );
58 return 1;
59 }
60 fp = fopen( fname, "w" );
61 fprintf( fp, "<?ilwd?>\n" );
62 if ( IS_TIME( ser->dom) )
63 {
64 fprintf( fp, "<ilwd name='%s::sequence' size='7'>\n", ser->name );
65 if ( ser->type == FR_VECT_8C )
66 {
67 fprintf( fp, "<lstring name='complex:domain' size='4'>TIME</lstring>\n" );
68 }
69 else
70 {
71 fprintf( fp, "<lstring name='real:domain' size='4'>TIME</lstring>\n" );
72 }
73 }
74 else
75 {
76 fprintf( fp, "<ilwd name='%s::sequence' size='9'>\n", ser->name );
77 if ( ser->type == FR_VECT_8C )
78 {
79 fprintf( fp, "<lstring name='complex:domain' size='4'>FREQ</lstring>\n" );
80 }
81 else
82 {
83 fprintf( fp, "<lstring name='real:domain' size='4'>FREQ</lstring>\n" );
84 }
85 }
86 fprintf( fp, "<int_4u name='gps_sec:start_time' units='sec'>%d</int_4u>\n",
87 ser->tbeg.gpsSeconds );
88 fprintf( fp, "<int_4u name='gps_nan:start_time' units='nanosec'>%d</int_4u>\n",
89 ser->tbeg.gpsNanoSeconds );
90 fprintf( fp, "<int_4u name='gps_sec:stop_time' units='sec'>%d</int_4u>\n",
91 ser->tend.gpsSeconds );
92 fprintf( fp, "<int_4u name='gps_nan:stop_time' units='nanosec'>%d</int_4u>\n",
93 ser->tend.gpsNanoSeconds );
94 if ( IS_TIME( ser->dom) )
95 {
96 fprintf( fp, "<real_8 name='time:step_size' units='sec'>%e</real_8>\n",
97 ser->step );
98 fprintf( fp, "<real_8 name='time:heterodyne_freq' units='Hz'>%e</real_8>\n",
99 ser->f0 );
100 }
101 else
102 {
103 fprintf( fp, "<real_8 name='start_freq' units='hz'>0</real_8>\n" );
104 fprintf( fp, "<real_8 name='stop_freq' units='hz'>%e</real_8>\n",
105 ( ser->size - 1 ) * ser->step );
106 fprintf( fp, "<real_8 name='freq:step_size' units='hz'>%e</real_8>\n",
107 ser->step );
108 }
109 if ( ser->type == FR_VECT_8C )
110 {
111 fprintf( fp, "<complex_8 dims='%d' name='data' units='%s'>",
112 (int)ser->size, ser->unit );
113 fprintf( fp, "%e %e", ser->data[0], ser->data[1] );
114 for ( i = 1; i < ser->size; ++i )
115 fprintf( fp, " %e %e", ser->data[2*i], ser->data[2*i+1] );
116 fprintf( fp, "</complex_8>\n" );
117 }
118 else
119 {
120 fprintf( fp, "<real_4 dims='%d' name='data' units='%s'>",
121 (int)ser->size, ser->unit );
122 fprintf( fp, "%e", ser->data[0] );
123 for ( i = 1; i < ser->size; ++i )
124 fprintf( fp, " %e", ser->data[i] );
125 fprintf( fp, "</real_4>\n" );
126 }
127 fprintf( fp, "</ilwd>\n" );
128 fclose( fp );
129 return 0;
130}
131
132FrameH *fr_add_proc_data( FrameH *frame, const struct series *ser )
133{
134 char *channel = ser->name;
135 /** \deprecated FIXME: the following code uses obsolete CVS ID tags.
136 * It should be modified to use git version information. */
137 char comment[] = "Generated by $Id$";
138 char seconds[] = "s";
139 char hertz[] = "Hz";
140 struct FrVect *vect;
141 struct FrProcData *proc;
142 size_t i;
143
144 if ( ser->type != FR_VECT_4R && ser->type != FR_VECT_8C &&
145 ser->type != FR_VECT_8R )
146 {
147 fprintf( stderr, "unknown data type in series: %d\nmust be 4R or 8C\n",
148 ser->type );
149 return NULL;
150 }
151
152 if ( ! frame )
153 {
154 char src[2];
155 src[0] = ser->name[0];
156 src[1] = 0;
157 frame = FrameHNew( src );
158 frame->run = 1;
159 frame->frame = 1;
160 frame->GTimeS = (int) ser->tbeg.gpsSeconds;
161 frame->GTimeN = (int) ser->tbeg.gpsNanoSeconds;
162 frame->dt = epoch_diff( &ser->tend, &ser->tbeg );
163 }
164
165 /* FIXME: work around for FrameL const string issue */
166 union { const char *c; char *s; } u = {ser->unit};
167
168 vect = FrVectNew1D( channel, ser->type, ser->size, ser->step,
169 IS_TIME( ser->dom) ? seconds : hertz, u.s );
170 proc = calloc( 1, sizeof( *proc ) );
171 proc->classe = FrProcDataDef();
172#if defined FR_VERS && FR_VERS < 5000
173 proc->sampleRate = IS_TIME( ser->dom ) ? 1.0 / ser->step : -1;
174#endif
175#if defined FR_VERS && FR_VERS >= 6000
176 proc->type = IS_TIME( ser->dom ) ? 1 : 2;
177 proc->subType = IS_TRANS( ser->dom ) ? 6 : 3;
178#endif
179 proc->fShift = ser->f0;
180 proc->data = vect;
181 proc->next = frame->procData;
182 frame->procData = proc;
183 FrStrCpy( &proc->name, channel );
184 FrStrCpy( &proc->comment, comment );
185 if ( ser->type == FR_VECT_8C )
186 {
187 for ( i = 0; i < ser->size; ++i )
188 {
189 vect->dataF[2*i] = ser->data[2*i];
190 vect->dataF[2*i+1] = ser->data[2*i+1];
191 }
192 }
193 else if ( ser->type == FR_VECT_4R )
194 {
195 for ( i = 0; i < ser->size; ++i )
196 {
197 vect->dataF[i] = ser->data[i];
198 }
199 }
200 else if ( ser->type == FR_VECT_8R )
201 {
202 for ( i = 0; i < ser->size; ++i )
203 {
204 vect->dataD[i] = ser->ddata[i];
205 }
206 }
207 else
208 {
209 fprintf( stderr, "unknown data type in series: %d\nmust be 4R or 8C\n",
210 ser->type );
211 return NULL;
212 }
213
214 return frame;
215}
#define fprintf
int s
double e
const double u
CHAR comment[LIGOMETA_COMMENT_MAX]
Definition: inspfrinj.c:350
int i
Definition: inspinj.c:596
proc
src
c
int
t2
t1
int t
void epoch_add(LIGOTimeGPS *t1, LIGOTimeGPS *t0, double dt)
Definition: series.c:39
double epoch_diff(const LIGOTimeGPS *t2, const LIGOTimeGPS *t1)
Definition: series.c:29
FrameH * fr_add_proc_data(FrameH *frame, const struct series *ser)
Definition: series.c:132
int write_ilwd(const char *fname, const struct series *ser)
Definition: series.c:50
#define IS_TRANS(domain_)
Definition: series.h:33
#define IS_TIME(domain_)
Definition: series.h:31
CHAR fname[256]
Definition: spininj.c:211
double t0
char * channel
INT4 gpsNanoSeconds
Definition: series.h:36
const char * unit
Definition: series.h:44
char * name
Definition: series.h:37
float f0
Definition: series.h:43
float * data
Definition: series.h:46
int type
Definition: series.h:41
size_t size
Definition: series.h:45
double step
Definition: series.h:42
double * ddata
Definition: series.h:47
LIGOTimeGPS tbeg
Definition: series.h:38
domain dom
Definition: series.h:40
LIGOTimeGPS tend
Definition: series.h:39
FILE * fp