File: tai-utc-gen.c

package info (click to toggle)
plplot 5.10.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 26,280 kB
  • ctags: 13,512
  • sloc: ansic: 83,001; xml: 27,081; ada: 18,878; cpp: 15,966; tcl: 11,651; python: 7,075; f90: 7,058; ml: 6,974; java: 6,665; perl: 5,029; sh: 2,210; makefile: 199; lisp: 75; sed: 25; fortran: 7
file content (186 lines) | stat: -rw-r--r-- 9,092 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//  $Id: tai-utc-gen.c 11971 2011-10-14 09:28:58Z andrewross $
//
//  Copyright (C) 2009 Alan W. Irwin
//
//  This file is part of PLplot.
//  PLplot is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Library General Public License as published
//  by the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  PLplot is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Library General Public License for more details.
//
//  You should have received a copy of the GNU Library General Public License
//  along with PLplot; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//

// Program for generating data structure used for containing tai-utc
// conversion information (linear transforms and leap seconds).
//
// The program assumes that argv[1] will be the input file, and
// argv[2] the output file.  This works cross-platform without
// worrying about shell redirects of stdin and stdout that are
// not accessible on Windows, apparently.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


//--------------------------------------------------------------------------
//   Function-like macro definitions
//--------------------------------------------------------------------------

#define MemError1( a )    do { fprintf( stderr, "MEMORY ERROR %d\n" a "\n", __LINE__ ); exit( __LINE__ ); } while ( 0 )

const char header[] = ""                                                                                 \
                      "/*\n"                                                                             \
                      "  This file is part of PLplot.\n"                                                 \
                      "  \n"                                                                             \
                      "  PLplot is free software; you can redistribute it and/or modify\n"               \
                      "  it under the terms of the GNU Library General Public License as published\n"    \
                      "  by the Free Software Foundation; either version 2 of the License, or\n"         \
                      "  (at your option) any later version.\n"                                          \
                      "  \n"                                                                             \
                      "  PLplot is distributed in the hope that it will be useful,\n"                    \
                      "  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"               \
                      "  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"                \
                      "  GNU Library General Public License for more details.\n"                         \
                      "  \n"                                                                             \
                      "  You should have received a copy of the GNU Library General Public License\n"    \
                      "  along with PLplot; if not, write to the Free Software\n"                        \
                      "  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" \
                      "  \n"                                                                             \
                      "  \n"                                                                             \
                      "  This header file contains the table containing the linear transforms \n"        \
                      "  for converting between TAI and UTC.\n"                                          \
                      "  It is an automatically generated file, so please do\n"                          \
                      "  not edit it directly. Make any changes to tai-utc.dat then use\n"               \
                      "  tai-utc-gen to recreate this header file.\n"                                    \
                      "  \n"                                                                             \
                      "  tai-utc.dat contains four essential fields to represent the following\n"        \
                      "  formula for the linear transformation between TAI and UTC: \n"                  \
                      "    TAI-UTC (seconds) = offset1 + (MJD-offset2)*slope\n"                          \
                      "  There are four essential fields per line in tai-utc.dat to represent\n"         \
                      "  this formula.  They are the Julian date (UTC) where the linear\n"               \
                      "  transformation implied by the line is first applied;\n"                         \
                      "  offset1 (seconds); offset2 (days), and slope (secs/day).\n"                     \
                      "  \n"                                                                             \
                      "*/";

int main( int argc, char *argv[] )
{
    FILE   *fr, *fw;
    char   readbuffer[256];
    int    *MJDstart = NULL;
    double *offset1  = NULL;
    int    *offset2  = NULL;
    double *slope    = NULL;
    double sec, *leap_sec = NULL;
    int    jd;
    int    i = 0;
    int    number_of_lines = 0;

    if ( ( argc < 2 ) || ( fr = fopen( argv[1], "r" ) ) == NULL )
    {
        fprintf( stderr, "Cannot open first file as readable\n" );
        exit( 1 );
    }

    if ( ( argc < 3 ) || ( fw = fopen( argv[2], "w" ) ) == NULL )
    {
        fprintf( stderr, "Cannot open second file as writable\n" );
        exit( 1 );
    }

    //
    //   Work out how many lines we have all up
    //

    while ( ( fgets( readbuffer, 255, fr ) != NULL ) )
    {
        ++number_of_lines;
    }

    //
    //   Allocate memory to the arrays which will hold the data
    //

    if ( ( MJDstart = (int *) calloc( (size_t) number_of_lines, (size_t) sizeof ( int ) ) ) == NULL )
        MemError1( "Allocating memory to the MJDstart table" );

    if ( ( offset1 = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
        MemError1( "Allocating memory to the offset1 table" );

    if ( ( offset2 = (int *) calloc( (size_t) number_of_lines, (size_t) sizeof ( int ) ) ) == NULL )
        MemError1( "Allocating memory to the offset2 table" );

    if ( ( slope = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
        MemError1( "Allocating memory to the slope table" );

    if ( ( leap_sec = (double *) calloc( (size_t) number_of_lines, (size_t) sizeof ( double ) ) ) == NULL )
        MemError1( "Allocating memory to the leap_sec table" );

    rewind( fr ); // Go back to the start of the file

    //
    //    Read in line by line, and copy the numbers into our arrays
    //

    while ( ( fgets( readbuffer, 255, fr ) != NULL ) )
    {
        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] );
        // Should be exact since all jd's in the file are integer+0.5
        MJDstart[i] = jd - 2400000;
        i++;
    }

    fclose( fr );

//
//   Write the data out to file ready to be included in our source
//


    fprintf( fw, "%s\n", header );

    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" );

    fprintf( fw, "const int number_of_entries_in_tai_utc_table=%d;\n\n", number_of_lines );

    fprintf( fw, "const TAI_UTC TAI_UTC_lookup_table[%d] = {\n", number_of_lines );
    for ( i = 0; i < number_of_lines; i++ )
    {
        sec = offset1[i] + (double) ( MJDstart[i] - offset2[i] ) * slope[i];
        if ( i == 0 )
            leap_sec[i] = 0.;
        else
            // sec is TAI-UTC in seconds calculated from UTC transformation
            // (equation 1 in README.tai-utc).  This calculation must be correct
            // for start of epoch range.  However, near end of epoch range where
            // ambiguities in UTC occur, must use equivalent TAI transformation
            // (equation 2 from same source) to calculate the UTC discontinuity
            // unambiguously.
            leap_sec[i] = sec - ( offset1[i - 1] + (double) ( MJDstart[i] + sec / 86400. - offset2[i - 1] ) * slope[i - 1] ) / ( 1. + slope[i - 1] / 86400. );
        if ( fabs( leap_sec[i] ) < 1.e-14 )
            leap_sec[i] = 0.;
        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] );
    }
    fprintf( fw, "};\n" );

    fclose( fw );
    free( MJDstart );
    free( offset1 );
    free( offset2 );
    free( slope );
    free( leap_sec );

    return ( 0 );
}