Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
create_time_correction_ephemeris.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2012 Matt Pitkin
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/* Many of these functions are (with occasional modification) taken directly
21 * from the TEMPO2 software package http://www.atnf.csiro.au/research/pulsar/tempo2/
22 * written by George Hobbs and Russell Edwards */
23
24/* create an ascii text ephemeris file of time delays to either convert from
25 * TT to TDB (as in TEMPO) or TT to TCB/Teph (from Irwin and Fukushima, 1999)
26 * as used in TEMPO2 */
27
29
30int verbose = 0;
31
32int main( int argc, char **argv )
33{
34 inputParams_t inputParams;
35
36 FILE *fp = NULL;
37
38 int i = 0, ne = 0;
39 long double mjdtt = 0.;
40 double deltaT = 0.;
41
42 struct tm beg, fin;
43
44 char outputfile[MAXFNAME];
45
46 /* get input arguments */
47 get_input_args( &inputParams, argc, argv );
48
49 /* create output file name */
50 beg = *XLALGPSToUTC( &beg, ( int )inputParams.startT );
51 fin = *XLALGPSToUTC( &fin, ( int )inputParams.endT );
52
53 /* make sure the year in the filename only covers full years */
54 if ( beg.tm_yday != 0 && beg.tm_hour != 0 && beg.tm_min != 0 && beg.tm_sec != 0 ) {
55 beg.tm_year++;
56 }
57 if ( fin.tm_yday != 0 && fin.tm_hour != 0 && fin.tm_min != 0 && fin.tm_sec != 0 ) {
58 fin.tm_year--;
59 }
60
61 if ( inputParams.et == TT2TCB ) {
62 if ( !sprintf( outputfile, "%s/te405_%d-%d.dat",
63 inputParams.outputpath, beg.tm_year + 1900, fin.tm_year + 1900 ) ) {
64 fprintf( stderr, "Error... problem creating output file name!\n" );
65 exit( 1 );
66 }
67 } else if ( inputParams.et == TT2TDB ) {
68 if ( !sprintf( outputfile, "%s/tdb_%d-%d.dat",
69 inputParams.outputpath, beg.tm_year + 1900, fin.tm_year + 1900 ) ) {
70 fprintf( stderr, "Error... problem creating output file name!\n" );
71 exit( 1 );
72 }
73 }
74
75 /* open the output file */
76 if ( ( fp = fopen( outputfile, "w" ) ) == NULL ) {
77 fprintf( stderr, "Error... can't open output file: %s!\n", outputfile );
78 exit( 1 );
79 }
80
81 ne = floor( ( inputParams.endT - inputParams.startT ) / inputParams.interval );
82
83 if ( verbose ) {
84 fprintf( stdout, "Creating ephemeris file from %lf to %lf, with %.2lf second\
85 time steps\n", inputParams.startT, inputParams.endT, inputParams.interval );
86 }
87
88 /* output header information on lines starting with a # comment */
89 fprintf( fp, "# Build information for %s\n", argv[0] );
90 fprintf( fp, "# Author: %s\n", lalPulsarVCSInfo.vcsAuthor );
91 fprintf( fp, "# LALPulsar Commit ID: %s\n", lalPulsarVCSInfo.vcsId );
92 fprintf( fp, "# LALPulsar Commit Date: %s\n", lalPulsarVCSInfo.vcsDate );
93 fprintf( fp, "#\n# Ephemeris creation command:-\n#\t" );
94 for ( INT4 k = 0; k < argc; k++ ) {
95 fprintf( fp, "%s ", argv[k] );
96 }
97 fprintf( fp, "\n" );
98
99 CHAR *efile = strrchr( inputParams.ephemfile, '/' );
100
101 fprintf( fp, "#\n# Time correction ephemeris file %s from TEMPO2 \
102(http://www.atnf.csiro.au/research/pulsar/tempo2/)\n", efile + 1 );
103 /* some information about the data */
104 fprintf( fp, "#\n# This file consists of a header line containing:\n" );
105 fprintf( fp, "#\tGPS start time, GPS end time, interval between entries \
106(secs), no. of entries\n" );
107 fprintf( fp, "# Each entry consists of:\n" );
108 fprintf( fp, "#\t dT (secs)\n" );
109 fprintf( fp, "# with entries calculated at the Terrestrial Time in MJD via \
110the conversion:\n\
111# TT(MJD) = 44244 + (GPS + 51.184)/86400\n" );
112
113 fprintf( fp, "%lf\t%lf\t%lf\t%d\n", inputParams.startT, inputParams.endT,
114 inputParams.interval, ne );
115
116 for ( i = 0; i < ne; i++ ) {
117 /* convert GPS to equivalent TT value (in MJD) */
118 mjdtt = MJDEPOCH + ( inputParams.startT + ( double )i * inputParams.interval +
119 GPS2TT ) / DAYSTOSEC;
120
121 /* these basically calculate the einstein delay */
122
123 /* using TEMPO2/TT to TCB/Teph file */
124 if ( inputParams.et == TT2TCB ) {
125 deltaT = IF_deltaT( mjdtt );
126 }
127 /* using TEMPO/TT to TDB file */
128 else if ( inputParams.et == TT2TDB ) {
129 deltaT = FB_deltaT( mjdtt, inputParams.ephemfile );
130 } else {
131 fprintf( stderr, "Error... unknown ephemeris type!\n" );
132 exit( 1 );
133 }
134
135 /* print output */
136 fprintf( fp, "%.16lf\n", deltaT );
137 }
138
140
141 fclose( fp );
142
143 return 0;
144}
145
146void get_input_args( inputParams_t *inputParams, int argc, char *argv[] )
147{
148 struct LALoption long_options[] = {
149 { "help", no_argument, 0, 'h' },
150 { "verbose", no_argument, &verbose, 1 },
151 { "ephem-type", required_argument, 0, 't'},
152 { "output-path", required_argument, 0, 'o'},
153 { "start", required_argument, 0, 's'},
154 { "interval", required_argument, 0, 'i'},
155 { "end", required_argument, 0, 'e'},
156 { 0, 0, 0, 0 }
157 };
158
159 char args[] = "ht:o:s:i:e:";
160 char *program = argv[0];
161
162 char *tempo2path;
163
164 if ( argc == 1 ) {
165 fprintf( stderr, "Error... no input parameters given! Try again!!!\n" );
166 exit( 0 );
167 }
168
169 /* set defaults */
170 inputParams->interval = 60.; /* default to 60 seconds between */
171
172 inputParams->startT = 883180814.; /* default start to 1 Jan 2008 00:00 UTC */
173 inputParams->endT = 1072569615.; /* default end to 1 Jan 2014 00:00 UTC */
174
175 inputParams->outputpath = NULL;
176
177 /* parse input arguments */
178 while ( 1 ) {
179 int option_index = 0;
180 int c;
181
182 c = LALgetopt_long( argc, argv, args, long_options, &option_index );
183 if ( c == -1 ) { /* end of options */
184 break;
185 }
186
187 switch ( c ) {
188 case 0:
189 if ( long_options[option_index].flag ) {
190 break;
191 } else
192 fprintf( stderr, "Error passing option %s with argument %s\n",
193 long_options[option_index].name, LALoptarg );
194#if __GNUC__ >= 7 && !defined __INTEL_COMPILER
195 __attribute__( ( fallthrough ) );
196#endif
197 case 'h': /* help message */
198 fprintf( stderr, USAGE, program );
199 exit( 0 );
200 case 't':
201 inputParams->ephemtype = XLALStringDuplicate( LALoptarg );
202 break;
203 case 'o':
204 inputParams->outputpath = XLALStringDuplicate( LALoptarg );
205 break;
206 case 's':
207 inputParams->startT = atof( LALoptarg );
208 break;
209 case 'e':
210 inputParams->endT = atof( LALoptarg );
211 break;
212 case 'i':
213 inputParams->interval = atof( LALoptarg );
214 break;
215 case '?':
216 default:
217 fprintf( stderr, "Unknown error while parsing options\n" );
218 }
219 }
220
221 if ( ( tempo2path = getenv( "TEMPO2" ) ) == NULL ) {
222 fprintf( stderr, "Error... TEMPO2 environment variable not set!\n" );
223 exit( 1 );
224 }
225
226 /* set the ephemeris file */
227 if ( !strcmp( inputParams->ephemtype, "TEMPO" ) ||
228 !strcmp( inputParams->ephemtype, "TDB" ) ) { /* using TEMPO/TDB file */
229 inputParams->et = TT2TDB;
230 sprintf( inputParams->ephemfile, "%s%s", tempo2path, TT2TDB_FILE );
231
232 if ( verbose ) {
233 fprintf( stdout, "Using TEMPO-style TT to TDB conversion file: %s\n",
234 inputParams->ephemfile );
235 }
236 }
237 /* using TEMPO2/TCB/Teph file */
238 else if ( !strcmp( inputParams->ephemtype, "TEMPO2" ) ||
239 !strcmp( inputParams->ephemtype, "TCB" ) ) {
240 inputParams->et = TT2TCB;
241 sprintf( inputParams->ephemfile, "%s%s", tempo2path, IFTEPH_FILE );
242
243 if ( verbose ) {
244 fprintf( stdout, "Using TEMPO2-style TT to te405 conversion file: %s\n",
245 inputParams->ephemfile );
246 }
247
248 /* open and initialise file */
249 IFTE_init( inputParams->ephemfile );
250 } else {
251 fprintf( stderr, "Error... unrecognised ephemeris type %s given.\n",
252 inputParams->ephemtype );
253 exit( 1 );
254 }
255}
256
257
258/* read in the TDB-TT ephemeris file and output the time delay. Copied from
259 the TEMPO2 tt2tdb.C file */
260double FB_deltaT( long double mjd_tt, char fname[MAXFNAME] )
261{
262 double ctatv; /* output TDB-TDT */
263 long double tdt; /* jd1 + jd2 (Julian date) */
264 static int tdbnrl = -1;
265 int nr, j, k, np;
266 double jda, jdb, tdbd1, tdbd2, t[2];
267 int tdbdt, tdbncf;
268 double dna, dt1, temp, pc[18], tc, twot;
269 static double buf[16];
270
271 /* Set up the TDB-TDT ephemeris file for reading */
272
273 /* Now do the calculations */
274 open_file( fname ); /* Open a Fortran made file for reading in C */
275 tdbd1 = read_double();
276 tdbd2 = read_double();
277 tdbdt = read_int();
278 tdbncf = read_int();
279 jda = read_double(); /* use jda as a dummy variable here */
280 jda = read_double(); /* use jda as a dummy variable here */
281 jda = read_double(); /* use jda as a dummy variable here */
282 jda = read_double(); /* use jda as a dummy variable here */
283 jda = read_double(); /* use jda as a dummy variable here */
284
285 /* Use the corrected TT time and convert to Julian date */
286 tdt = mjd_tt + 2400000.5;
287 if ( tdt - ( int )tdt >= 0.5 ) {
288 jda = ( int )tdt + 0.5;
289 jdb = tdt - ( int )tdt - 0.5;
290 } else {
291 jda = ( int )tdt - 0.5;
292 jdb = tdt - ( int )tdt + 0.5;
293 }
294 nr = ( int )( ( jda - tdbd1 ) / tdbdt ) + 2;
295 if ( nr < 1 || tdt > tdbd2 ) {
296 printf( "ERROR [CLK4]: Date %.10f out of range of TDB-TDT \
297table\n", ( double )tdt );
298 exit( 1 );
299 }
300 if ( nr != tdbnrl ) {
301 tdbnrl = nr;
302 /* MUST JUMP TO RECORD NR IN THE FILE */
303 for ( j = 0; j < nr - 1; j++ )
304 for ( k = 0; k < tdbncf; k++ ) {
305 buf[k] = read_double();
306 }
307 }
308 t[0] = ( ( jda - ( ( nr - 2 ) * tdbdt + tdbd1 ) ) + jdb ) / tdbdt; /* Fraction within record */
309 t[1] = 1.0; /* Unused */
310
311 /* Interpolation: call interp(buf,t,tdbncf,1, 1, 1, ctatv) */
312 np = 2;
313 twot = 0.0;
314
315 pc[0] = 1.0;
316 pc[1] = 0.0;
317
318 dna = 1.0;
319 dt1 = ( int )( t[0] );
320 temp = dna * t[0];
321 tc = 2.0 * ( fortran_mod( temp, 1.0 ) + dt1 ) - 1.0;
322
323 if ( tc != pc[1] ) {
324 np = 2;
325 pc[1] = tc;
326 twot = tc + tc;
327 }
328 if ( np < tdbncf ) {
329 for ( k = np + 1; k <= tdbncf; k++ ) {
330 pc[k - 1] = twot * pc[k - 2] - pc[k - 3];
331 }
332 np = tdbncf;
333 }
334 ctatv = 0.0;
335 for ( j = tdbncf; j >= 1; j-- ) {
336 ctatv = ctatv + pc[j - 1] * buf[j - 1];
337 }
338
339 close_file();
340
341 return ctatv;
342}
343
344
345double IF_deltaT( long double mjd_tt )
346{
347 return IFTE_DeltaT( 2400000.0 + ( int )mjd_tt, 0.5 + ( mjd_tt - ( int )mjd_tt ) ) * DAYSTOSEC;
348}
349
350/******************* FORTRAN FILE READING FUNCTIONS ************************/
351/* taken from TEMPO2 read_fortran.h */
352
355
356int open_file( char fname[MAXFNAME] )
357{
358 int i;
359
360 /* NOTE MUST PUT BACK TO 0 FOR SOLARIS!!!!! */
361 union Convert {
362 char asChar[sizeof( int )];
363 int asInt;
364 } intcnv;
365
366 intcnv.asInt = 1;
367 if ( intcnv.asChar[0] == 1 ) {
368 swapByte = 1;
369 } else {
370 swapByte = 0;
371 }
372
373 /* Look for blank character in filename */
374 for ( i = 0; fname[i]; i++ ) {
375 if ( fname[i] == ' ' ) {
376 fname[i] = '\0';
377 break;
378 }
379 }
380 if ( ( c_fileptr = fopen( fname, "rb" ) ) == NULL ) {
381 fprintf( stderr, "Error: Unable to open filename %s\n", fname );
382 exit( 1 );
383 }
384 return 0;
385}
386
387void close_file( void )
388{
389 fclose( c_fileptr );
390}
391
392int read_int( void )
393{
394 int i;
395
396 union Convert {
397 char asChar[sizeof( int )];
398 int asInt;
399 } intcnv;
400
401 if ( swapByte == 1 ) {
402 for ( i = sizeof( int ) -1; i >= 0; i-- ) {
403 intcnv.asChar[i] = fgetc( c_fileptr );
404 }
405 } else {
406 for ( i = 0; i < ( int )sizeof( int ); i++ ) {
407 intcnv.asChar[i] = fgetc( c_fileptr );
408 }
409 }
410 return intcnv.asInt;
411}
412
413double read_double( void )
414{
415 int i;
416
417 union Convert {
418 char asChar[sizeof( double )];
419 double asDouble;
420 } dblcnv;
421
422 if ( swapByte == 1 ) {
423 for ( i = sizeof( double ) -1; i >= 0; i-- ) {
424 dblcnv.asChar[i] = fgetc( c_fileptr );
425 }
426 } else {
427 for ( i = 0; i < ( int )sizeof( double ); i++ ) {
428 dblcnv.asChar[i] = fgetc( c_fileptr );
429 }
430 }
431 return dblcnv.asDouble;
432}
433
434/* taken from TEMPO2 temp2Util.C */
435double fortran_mod( double a, double p )
436{
437 double ret;
438 ret = a - ( int )( a / p ) * p;
439 return ret;
440}
441
442/**** FUNCTIONS FROM TEMPO2 ifteph.C file ***********/
443
444void IFTE_init( const char fname[MAXFNAME] )
445{
446 FILE *f;
447 char buf[1024];
448 int ncon;
449 double double_in;
450 size_t rc;
451
452 if ( ( f = fopen( fname, "r" ) ) == NULL ) {
453 fprintf( stderr, "Error... opening time ephemeris file '%s'\n",
454 fname );
455 exit( 1 );
456 }
457
458 /* read in header info */
459 rc = fread( buf, 1, 252, f ); /* read CHARACTER*6 TTL(14,3) */
460 rc = fread( buf, 1, 12, f ); /* read CHARACTER*6 CNAM(2) */
461 rc = fread( &ifte.startJD, 1, 8, f );
462 rc = fread( &ifte.endJD, 1, 8, f );
463 rc = fread( &ifte.stepJD, 1, 8, f );
464 rc = fread( &ncon, 1, 4, f );
465
466 ifte.swap_endian = ( ncon != 2 ); /* check for endianness */
467
468 if ( ifte.swap_endian ) {
469 IFTswapInt( &ncon );
470 }
471 if ( ncon != 2 ) { /* check that we can decode the file */
472 fprintf( stderr, "Cannot understand format of time ephemeris file '%s'!\n",
473 fname );
474 exit( 1 );
475 }
476 if ( ifte.swap_endian ) {
480 }
481
482 rc = fread( ifte.ipt, 8, 3, f );
483 if ( ifte.swap_endian ) {
484 IFTswapInts( &ifte.ipt[0][0], 6 );
485 }
486
487 /* figure out the record length */
488 ifte.reclen = 4 * 2 * ( ifte.ipt[1][0] - 1 + 3 * ifte.ipt[1][1] * ifte.ipt[1][2] );
489
490 /* get the constants from record "2" */
491 fseek( f, ifte.reclen, SEEK_SET );
492 rc = fread( &double_in, 8, 1, f );
493 if ( ifte.swap_endian ) {
494 IFTswapDouble( &double_in );
495 }
496 ifte.ephver = ( int )floor( double_in );
497 rc = fread( &ifte.L_C, 8, 1, f );
498 if ( ifte.swap_endian ) {
500 }
501
502 if ( rc == 0 ) {
503 fprintf( stderr, "Error... problem reading header from time ephemeris file \
504'%s'\n", fname );
505 exit( 1 );
506 }
507
508 ifte.f = f;
509 ifte.iinfo.np = 2;
510 ifte.iinfo.nv = 3;
511 ifte.iinfo.pc[0] = 1.0;
512 ifte.iinfo.pc[1] = 0.0;
513 ifte.iinfo.vc[1] = 1.0;
514 ifte.irec = -1;
515 /* Note: file is not closed as it is used by other routines */
516}
517
518void IFTE_close_file( void )
519{
520 if ( ifte.f != NULL ) {
521 fclose( ifte.f );
522 }
523}
524
525/* functions for swapping endianess */
526void IFTswap4( char *word )
527{
528 char tmp;
529 tmp = word[0];
530 word[0] = word[3];
531 word[3] = tmp;
532 tmp = word[1];
533 word[1] = word[2];
534 word[2] = tmp;
535}
536
537void IFTswapInt( int *word )
538{
539 IFTswap4( ( char * )word );
540}
541
542void IFTswapInts( int *word, int n )
543{
544 int i;
545 for ( i = 0; i < n; i++ ) {
546 IFTswap4( ( char * )( word + i ) );
547 }
548}
549
550void IFTswap8( char *dword )
551{
552 char tmp;
553 tmp = dword[0];
554 dword[0] = dword[7];
555 dword[7] = tmp;
556 tmp = dword[1];
557 dword[1] = dword[6];
558 dword[6] = tmp;
559 tmp = dword[2];
560 dword[2] = dword[5];
561 dword[5] = tmp;
562 tmp = dword[3];
563 dword[3] = dword[4];
564 dword[4] = tmp;
565}
566
567void IFTswapDouble( double *dbl )
568{
569 IFTswap8( ( char * )dbl );
570}
571
572void IFTswap8N( char *dwords, int n )
573{
574 char tmp;
575 int i;
576 for ( i = 0; i < n; i++ ) {
577 tmp = dwords[0];
578 dwords[0] = dwords[7];
579 dwords[7] = tmp;
580 tmp = dwords[1];
581 dwords[1] = dwords[6];
582 dwords[6] = tmp;
583 tmp = dwords[2];
584 dwords[2] = dwords[5];
585 dwords[5] = tmp;
586 tmp = dwords[3];
587 dwords[3] = dwords[4];
588 dwords[4] = tmp;
589 dwords += 8;
590 }
591}
592
593void IFTswapDoubles( double *dbl, int N )
594{
595 IFTswap8N( ( char * )dbl, N );
596}
597
598/* general purpose value-getter */
599void IFTE_get_Vals( double JDeph0, double JDeph1, int kind,
600 double *res )
601{
602 double whole0, whole1, frac0, frac1;
603 int irec;
604 double t[2];
605 int ncoeff = ifte.reclen / 8;
606 size_t nread;
607
608 whole0 = floor( JDeph0 - 0.5 );
609 frac0 = JDeph0 - 0.5 - whole0;
610 whole1 = floor( JDeph1 );
611 frac1 = JDeph1 - whole1;
612 whole0 += whole1 + 0.5;
613 frac0 += frac1;
614 whole1 = floor( frac0 );
615 frac1 = frac0 - whole1;
616 whole0 += whole1;
617
618 JDeph0 = whole0;
619 JDeph1 = frac1;
620
621 if ( JDeph0 < ifte.startJD ) {
622 fprintf( stderr, "Error: Requested JD=%lf is less than start JD=%lf\n",
623 JDeph0, ifte.startJD );
624 exit( 1 );
625 }
626
627 /* CALCULATE RECORD # AND RELATIVE TIME IN INTERVAL */
628 irec = ( int )floor( ( JDeph0 - ifte.startJD ) / ifte.stepJD ) + 2;
629
630 if ( JDeph0 == ifte.endJD ) {
631 irec--;
632 }
633
634 t[0] = ( JDeph0 - ( ifte.startJD + ifte.stepJD * ( irec - 2 ) ) + JDeph1 ) / ifte.stepJD;
635 t[1] = ifte.stepJD;
636
637 if ( irec != ifte.irec ) {
638 if ( fseek( ifte.f, ifte.reclen * irec, SEEK_SET ) < 0 ) {
639 fprintf( stderr, "Error reading time ephemeris" );
640 exit( 1 );
641 }
642 nread = fread( ifte.buf, 8, ncoeff, ifte.f );
643 if ( ( int )nread < ncoeff ) {
644 fprintf( stderr, "Error reading time ephemeris: Only read %zd coefficients,\
645 wanted %d!\n", nread, ncoeff );
646 exit( 1 );
647 }
648 if ( ifte.swap_endian ) {
649 IFTswapDoubles( ifte.buf, ncoeff );
650 }
651 }
652
653 /* INTERPOLATE time ephemeris */
654 if ( kind == 1 )
655 IFTEinterp( &ifte.iinfo, ifte.buf + ifte.ipt[0][0] - 1, t,
656 ifte.ipt[0][1], 1, ifte.ipt[0][2], 2, res );
657 else
658 IFTEinterp( &ifte.iinfo, ifte.buf + ifte.ipt[1][0] - 1, t,
659 ifte.ipt[1][1], 3, ifte.ipt[1][2], 2, res );
660}
661
662/* convenience interfaces */
663void IFTE_get_DeltaT_DeltaTDot( double Teph0, double Teph1,
664 double *DeltaT, double *DeltaTDot )
665{
666 double res[2];
667 IFTE_get_Vals( Teph0, Teph1, 1, res );
668 *DeltaT = res[0];
669 *DeltaTDot = res[1];
670}
671
672double IFTE_DeltaT( double Teph0, double Teph1 )
673{
674 double DeltaT, DeltaTDot;
675 IFTE_get_DeltaT_DeltaTDot( Teph0, Teph1, &DeltaT, &DeltaTDot );
676 return DeltaT;
677}
678
679/* The following routine is borrowed from the JPL ephemeris C code */
680/*****************************************************************************
681* ***** jpl planetary and lunar ephemerides ***** C ver.1.2 *
682******************************************************************************
683* *
684* This program was written in standard fortran-77 and it was manually *
685* translated to C language by Piotr A. Dybczynski (dybol@phys.amu.edu.pl), *
686* subsequently revised heavily by Bill J Gray (pluto@gwi.net). *
687* *
688******************************************************************************/
689
690/*****************************************************************************
691** interp(buf,t,ncf,ncm,na,ifl,pv) **
692******************************************************************************
693** **
694** this subroutine differentiates and interpolates a **
695** set of chebyshev coefficients to give position and velocity **
696** **
697** calling sequence parameters: **
698** **
699** input: **
700** **
701** iinfo stores certain chunks of interpolation info, in hopes **
702** that if you call again with similar parameters, the **
703** function won't have to re-compute all coefficients/data. **
704** **
705** coef 1st location of array of d.p. chebyshev coefficients **
706** of position **
707** **
708** t t[0] is double fractional time in interval covered by **
709** coefficients at which interpolation is wanted **
710** (0 <= t[0] <= 1). t[1] is dp length of whole **
711** interval in input time units. **
712** **
713** ncf # of coefficients per component **
714** **
715** ncm # of components per set of coefficients **
716** **
717** na # of sets of coefficients in full array **
718** (i.e., # of sub-intervals in full interval) **
719** **
720** ifl integer flag: =1 for positions only **
721** =2 for pos and vel **
722** **
723** **
724** output: **
725** **
726** posvel interpolated quantities requested. dimension **
727** expected is posvel[ncm*ifl], double precision. **
728** **
729*****************************************************************************/
730static void IFTEinterp( struct IFTE_interpolation_info *iinfo,
731 const double coef[], const double t[2], const int ncf,
732 const int ncm, const int na, const int ifl, double posvel[] )
733{
734 double dna, dt1, temp, tc, vfac, temp1;
735 double *pc_ptr;
736 int l, i, j;
737
738 /* entry point. get correct sub-interval number for this set
739 of coefficients and then get normalized chebyshev time
740 within that subinterval. */
741
742 dna = ( double )na;
743 modf( t[0], &dt1 );
744 temp = dna * t[0];
745 l = ( int )( temp - dt1 );
746
747 /* tc is the normalized chebyshev time (-1 <= tc <= 1) */
748 tc = 2.0 * ( modf( temp, &temp1 ) + dt1 ) - 1.0;
749
750 /* check to see whether chebyshev time has changed,
751 and compute new polynomial values if it has.
752 (the element iinfo->pc[1] is the value of t1[tc] and hence
753 contains the value of tc on the previous call.) */
754
755 if ( tc != iinfo->pc[1] ) {
756 iinfo->np = 2;
757 iinfo->nv = 3;
758 iinfo->pc[1] = tc;
759 iinfo->twot = tc + tc;
760 }
761
762 /* be sure that at least 'ncf' polynomials have been evaluated
763 and are stored in the array 'iinfo->pc'. */
764
765 if ( iinfo->np < ncf ) {
766 pc_ptr = iinfo->pc + iinfo->np;
767
768 for ( i = ncf - iinfo->np; i; i--, pc_ptr++ ) {
769 *pc_ptr = iinfo->twot * pc_ptr[-1] - pc_ptr[-2];
770 }
771 iinfo->np = ncf;
772 }
773
774 /* interpolate to get position for each component */
775 for ( i = 0; i < ncm; ++i ) { /* ncm is a number of coordinates */
776 const double *coeff_ptr = coef + ncf * ( i + l * ncm + 1 );
777 const double *pc_ptr2 = iinfo->pc + ncf;
778
779 posvel[i] = 0.0;
780 for ( j = ncf; j; j-- ) {
781 posvel[i] += ( *--pc_ptr2 ) * ( *--coeff_ptr );
782 }
783 }
784
785 if ( ifl <= 1 ) {
786 return;
787 }
788
789 /* if velocity interpolation is wanted, be sure enough
790 derivative polynomials have been generated and stored. */
791
792 vfac = ( dna + dna ) / t[1];
793 iinfo->vc[2] = iinfo->twot + iinfo->twot;
794 if ( iinfo->nv < ncf ) {
795 double *vc_ptr = iinfo->vc + iinfo->nv;
796 const double *pc_ptr2 = iinfo->pc + iinfo->nv - 1;
797
798 for ( i = ncf - iinfo->nv; i; i--, vc_ptr++, pc_ptr2++ ) {
799 *vc_ptr = iinfo->twot * vc_ptr[-1] + *pc_ptr2 + *pc_ptr2 - vc_ptr[-2];
800 }
801 iinfo->nv = ncf;
802 }
803
804 /* interpolate to get velocity for each component */
805 for ( i = 0; i < ncm; ++i ) {
806 double tval = 0.;
807 const double *coeff_ptr = coef + ncf * ( i + l * ncm + 1 );
808 const double *vc_ptr = iinfo->vc + ncf;
809
810 for ( j = ncf; j; j-- ) {
811 tval += ( *--vc_ptr ) * ( *--coeff_ptr );
812 }
813 posvel[ i + ncm] = tval * vfac;
814 }
815
816 return;
817}
const char * program
int j
int k
const LALVCSInfo lalPulsarVCSInfo
VCS and build information for LALPulsar.
#define c
int LALgetopt_long(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
char * LALoptarg
#define no_argument
#define required_argument
ParConversion pc[NUM_PARS]
Initialise conversion structure with most allowed TEMPO2 parameter names and conversion functions (co...
const char * name
Definition: SearchTiming.c:93
#define fprintf
int l
void IFTE_init(const char fname[MAXFNAME])
double FB_deltaT(long double mjd_tt, char fname[MAXFNAME])
int main(int argc, char **argv)
void IFTswap8N(char *dwords, int n)
double fortran_mod(double a, double p)
void get_input_args(inputParams_t *inputParams, int argc, char *argv[])
int open_file(char fname[MAXFNAME])
void IFTswapInts(int *word, int n)
double IFTE_DeltaT(double Teph0, double Teph1)
void close_file(void)
void IFTswapDoubles(double *dbl, int N)
double read_double(void)
static void IFTEinterp(struct IFTE_interpolation_info *iinfo, const double coef[], const double t[2], const int ncf, const int ncm, const int na, const int ifl, double posvel[])
void IFTswap4(char *word)
void IFTE_close_file(void)
void IFTE_get_Vals(double JDeph0, double JDeph1, int kind, double *res)
void IFTswap8(char *dword)
double IF_deltaT(long double mjd_tt)
void IFTswapInt(int *word)
void IFTswapDouble(double *dbl)
void IFTE_get_DeltaT_DeltaTDot(double Teph0, double Teph1, double *DeltaT, double *DeltaTDot)
static IFTEphemeris ifte
#define __attribute__(x)
char CHAR
int32_t INT4
char char * XLALStringDuplicate(const char *s)
static const INT4 a
struct tm * XLALGPSToUTC(struct tm *utc, INT4 gpssec)
temp
n
tc
int N
struct IFTE_interpolation_info iinfo
const char *const vcsDate
const char *const vcsAuthor
const char *const vcsId
int * flag
double deltaT