PLplot: tai-utc-gen.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tai-utc-gen.c
Go to the documentation of this file.
1 // $Id: tai-utc-gen.c 11971 2011-10-14 09:28:58Z andrewross $
2 //
3 // Copyright (C) 2009 Alan W. Irwin
4 //
5 // This file is part of PLplot.
6 // PLplot is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU Library General Public License as published
8 // by the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // PLplot is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public License
17 // along with PLplot; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 //
21
22 // Program for generating data structure used for containing tai-utc
23 // conversion information (linear transforms and leap seconds).
24 //
25 // The program assumes that argv[1] will be the input file, and
26 // argv[2] the output file. This works cross-platform without
27 // worrying about shell redirects of stdin and stdout that are
28 // not accessible on Windows, apparently.
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34
35
36 //--------------------------------------------------------------------------
37 // Function-like macro definitions
38 //--------------------------------------------------------------------------
39
40 #define MemError1( a ) do { fprintf( stderr, "MEMORY ERROR %d\n" a "\n", __LINE__ ); exit( __LINE__ ); } while ( 0 )
41
42 const char header[] = "" \
43 "/*\n" \
44 " This file is part of PLplot.\n" \
45 " \n" \
46 " PLplot is free software; you can redistribute it and/or modify\n" \
47 " it under the terms of the GNU Library General Public License as published\n" \
48 " by the Free Software Foundation; either version 2 of the License, or\n" \
49 " (at your option) any later version.\n" \
50 " \n" \
51 " PLplot is distributed in the hope that it will be useful,\n" \
52 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
53 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \
54 " GNU Library General Public License for more details.\n" \
55 " \n" \
56 " You should have received a copy of the GNU Library General Public License\n" \
57 " along with PLplot; if not, write to the Free Software\n" \
58 " Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" \
59 " \n" \
60 " \n" \
61 " This header file contains the table containing the linear transforms \n" \
62 " for converting between TAI and UTC.\n" \
63 " It is an automatically generated file, so please do\n" \
64 " not edit it directly. Make any changes to tai-utc.dat then use\n" \
65 " tai-utc-gen to recreate this header file.\n" \
66 " \n" \
67 " tai-utc.dat contains four essential fields to represent the following\n" \
68 " formula for the linear transformation between TAI and UTC: \n" \
69 " TAI-UTC (seconds) = offset1 + (MJD-offset2)*slope\n" \
70 " There are four essential fields per line in tai-utc.dat to represent\n" \
71 " this formula. They are the Julian date (UTC) where the linear\n" \
72 " transformation implied by the line is first applied;\n" \
73 " offset1 (seconds); offset2 (days), and slope (secs/day).\n" \
74 " \n" \
75 "*/";
76
77 int main( int argc, char *argv[] )
78 {
79 FILE *fr, *fw;
80 char readbuffer[256];
81 int *MJDstart = NULL;
82 double *offset1 = NULL;
83 int *offset2 = NULL;
84 double *slope = NULL;
85 double sec, *leap_sec = NULL;
86 int jd;
87 int i = 0;
88 int number_of_lines = 0;
89
90 if ( ( argc < 2 ) || ( fr = fopen( argv[1], "r" ) ) == NULL )
91 {
92 fprintf( stderr, "Cannot open first file as readable\n" );
93 exit( 1 );
94 }
95
96 if ( ( argc < 3 ) || ( fw = fopen( argv[2], "w" ) ) == NULL )
97 {
98 fprintf( stderr, "Cannot open second file as writable\n" );
99 exit( 1 );
100 }
101
102 //
103 // Work out how many lines we have all up
104 //
105
106 while ( ( fgets( readbuffer, 255, fr ) != NULL ) )
107 {
108 ++number_of_lines;
109 }
110
111 //
112 // Allocate memory to the arrays which will hold the data
113 //
114
115 if ( ( MJDstart = (int *) calloc( (size_t) number_of_lines, (size_t) sizeof ( int ) ) ) == NULL )
116 MemError1( "Allocating memory to the MJDstart table" );
117
118 if ( ( offset1 = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
119 MemError1( "Allocating memory to the offset1 table" );
120
121 if ( ( offset2 = (int *) calloc( (size_t) number_of_lines, (size_t) sizeof ( int ) ) ) == NULL )
122 MemError1( "Allocating memory to the offset2 table" );
123
124 if ( ( slope = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
125 MemError1( "Allocating memory to the slope table" );
126
127 if ( ( leap_sec = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
128 MemError1( "Allocating memory to the leap_sec table" );
129
130 rewind( fr ); // Go back to the start of the file
131
132 //
133 // Read in line by line, and copy the numbers into our arrays
134 //
135
136 while ( ( fgets( readbuffer, 255, fr ) != NULL ) )
137 {
138 sscanf( readbuffer, "%*s %*s %*s %*s %d.5 %*s %lf %*s %*s %*s %*s %d.) X %lf S", (int *) &jd, (double *) &offset1[i], (int *) &offset2[i], (double *) &slope[i] );
139 // Should be exact since all jd's in the file are integer+0.5
140 MJDstart[i] = jd - 2400000;
141 i++;
142 }
143
144 fclose( fr );
145
146 //
147 // Write the data out to file ready to be included in our source
148 //
149
150
151 fprintf( fw, "%s\n", header );
152
153 fprintf( fw, "typedef struct {\n\tint base_day;\n\tdouble time_sec_tai;\n\tdouble time_sec_utc;\n\tdouble size_prev_leap_sec;\n\tdouble offset1;\n\tint offset2;\n\tdouble slope;\n} TAI_UTC;\n\n" );
154
155 fprintf( fw, "const int number_of_entries_in_tai_utc_table=%d;\n\n", number_of_lines );
156
157 fprintf( fw, "const TAI_UTC TAI_UTC_lookup_table[%d] = {\n", number_of_lines );
158 for ( i = 0; i < number_of_lines; i++ )
159 {
160 sec = offset1[i] + (double) ( MJDstart[i] - offset2[i] ) * slope[i];
161 if ( i == 0 )
162 leap_sec[i] = 0.;
163 else
164 // sec is TAI-UTC in seconds calculated from UTC transformation
165 // (equation 1 in README.tai-utc). This calculation must be correct
166 // for start of epoch range. However, near end of epoch range where
167 // ambiguities in UTC occur, must use equivalent TAI transformation
168 // (equation 2 from same source) to calculate the UTC discontinuity
169 // unambiguously.
170 leap_sec[i] = sec - ( offset1[i - 1] + (double) ( MJDstart[i] + sec / 86400. - offset2[i - 1] ) * slope[i - 1] ) / ( 1. + slope[i - 1] / 86400. );
171 if ( fabs( leap_sec[i] ) < 1.e-14 )
172 leap_sec[i] = 0.;
173 fprintf( fw, "{%d, %15.8f, 0., %20.14f, %15.8f, %d, %15.8f},\n", MJDstart[i], sec, leap_sec[i], offset1[i], offset2[i], slope[i] );
174 }
175 fprintf( fw, "};\n" );
176
177 fclose( fw );
178 free( MJDstart );
179 free( offset1 );
180 free( offset2 );
181 free( slope );
182 free( leap_sec );
183
184 return ( 0 );
185 }
186