LALPulsar  6.1.0.1-c9a8ef6
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 
30 int verbose = 0;
31 
32 int 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 \
110 the 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 
139  IFTE_close_file();
140 
141  fclose( fp );
142 
143  return 0;
144 }
145 
146 void 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 */
260 double 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 \
297 table\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 
345 double 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 
353 FILE *c_fileptr;
355 
356 int 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 
387 void close_file( void )
388 {
389  fclose( c_fileptr );
390 }
391 
392 int 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 
413 double 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 */
435 double 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 
444 void 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 ) {
499  IFTswapDouble( &ifte.L_C );
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 
518 void IFTE_close_file( void )
519 {
520  if ( ifte.f != NULL ) {
521  fclose( ifte.f );
522  }
523 }
524 
525 /* functions for swapping endianess */
526 void 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 
537 void IFTswapInt( int *word )
538 {
539  IFTswap4( ( char * )word );
540 }
541 
542 void IFTswapInts( int *word, int n )
543 {
544  int i;
545  for ( i = 0; i < n; i++ ) {
546  IFTswap4( ( char * )( word + i ) );
547  }
548 }
549 
550 void 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 
567 void IFTswapDouble( double *dbl )
568 {
569  IFTswap8( ( char * )dbl );
570 }
571 
572 void 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 
593 void IFTswapDoubles( double *dbl, int N )
594 {
595  IFTswap8N( ( char * )dbl, N );
596 }
597 
598 /* general purpose value-getter */
599 void 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 */
663 void 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 
672 double 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 *****************************************************************************/
730 static 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 }
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
const double deltaT
#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