Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Guilhem Bonnefille
Orekit
Commits
525d4d2a
Commit
525d4d2a
authored
Dec 04, 2020
by
Luc Maisonobe
Browse files
Added loading of AGI LeapSecond.dat files.
Fixes
#737
parent
46cc7802
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/changes/changes.xml
View file @
525d4d2a
...
...
@@ -21,6 +21,9 @@
</properties>
<body>
<release
version=
"10.3"
date=
"TBD"
description=
"TBD"
>
<action
dev=
"luc"
type=
"add"
issue=
"737"
>
Added loading of AGI LeapSecond.dat files.
</action>
<action
dev=
"raphael"
type=
"add"
issue=
"686"
>
Allowed user-defined format for ephemeris data lines in
StreamingAemWriter, AEMWriter, StreamingOemWriter and OEMWriter.
...
...
src/main/java/org/orekit/time/AGILeapSecondFilesLoader.java
0 → 100644
View file @
525d4d2a
/* Copyright 2002-2020 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.orekit.time
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.nio.charset.StandardCharsets
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
org.hipparchus.util.FastMath
;
import
org.orekit.annotation.DefaultDataContext
;
import
org.orekit.data.AbstractSelfFeedingLoader
;
import
org.orekit.data.DataContext
;
import
org.orekit.data.DataProvidersManager
;
import
org.orekit.errors.OrekitException
;
import
org.orekit.errors.OrekitMessages
;
/** Loader for UTC-TAI extracted from LeapSecond file from AGI.
* <p>
* This class is immutable and hence thread-safe
* </p>
* @see <a href="ftp://ftp.agi.com/pub/STKData/Astro/LeapSecond.dat">LeapSecond.dat</a>
* @author Luc Maisonobe
* @since 10.3
*/
public
class
AGILeapSecondFilesLoader
extends
AbstractSelfFeedingLoader
implements
UTCTAIOffsetsLoader
{
/** Default supported files name pattern. */
public
static
final
String
DEFAULT_SUPPORTED_NAMES
=
"^LeapSecond\\.dat$"
;
/**
* Build a loader for LeapSecond.dat file from AGI. This constructor uses the {@link
* DataContext#getDefault() default data context}.
*
* @param supportedNames regular expression for supported files names
* @see #TAIUTCDatFilesLoader(String, DataProvidersManager)
*/
@DefaultDataContext
public
AGILeapSecondFilesLoader
(
final
String
supportedNames
)
{
this
(
supportedNames
,
DataContext
.
getDefault
().
getDataProvidersManager
());
}
/**
* Build a loader for LeapSecond.dat file from AGI.
*
* @param supportedNames regular expression for supported files names
* @param manager provides access to the {@code tai-utc.dat} file.
*/
public
AGILeapSecondFilesLoader
(
final
String
supportedNames
,
final
DataProvidersManager
manager
)
{
super
(
supportedNames
,
manager
);
}
/** {@inheritDoc} */
@Override
public
List
<
OffsetModel
>
loadOffsets
()
{
final
UtcTaiOffsetLoader
parser
=
new
UtcTaiOffsetLoader
(
new
Parser
());
this
.
feed
(
parser
);
return
parser
.
getOffsets
();
}
/** Internal class performing the parsing. */
public
static
class
Parser
implements
UTCTAIOffsetsLoader
.
Parser
{
/** Regular expression for optional blanks. */
private
static
final
String
BLANKS
=
"\\p{Blank}*"
;
/** Regular expression for storage start. */
private
static
final
String
STORAGE_START
=
"("
;
/** Regular expression for storage end. */
private
static
final
String
STORAGE_END
=
")"
;
/** Regular expression for alternative. */
private
static
final
String
ALTERNATIVE
=
"|"
;
/** Regular expression matching blanks at start of line. */
private
static
final
String
LINE_START_REGEXP
=
"^"
+
BLANKS
;
/** Regular expression matching blanks at end of line. */
private
static
final
String
LINE_END_REGEXP
=
BLANKS
+
"$"
;
/** Regular expression matching integers. */
private
static
final
String
INTEGER_REGEXP
=
"[-+]?\\p{Digit}+"
;
/** Regular expression matching real numbers. */
private
static
final
String
REAL_REGEXP
=
"[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?"
;
/** Regular expression matching an integer field to store. */
private
static
final
String
STORED_INTEGER_FIELD
=
BLANKS
+
STORAGE_START
+
INTEGER_REGEXP
+
STORAGE_END
;
/** Regular expression matching a real field to store. */
private
static
final
String
STORED_REAL_FIELD
=
BLANKS
+
STORAGE_START
+
REAL_REGEXP
+
STORAGE_END
;
/** Data lines pattern. */
private
Pattern
dataPattern
;
/** Simple constructor.
*/
public
Parser
()
{
// data lines read:
// 28
// 1972 JAN 1 2441317.5 10.0 41317. 0.0
// 1972 JUL 1 2441499.5 11.0 41317. 0.0
// 1973 JAN 1 2441683.5 12.0 41317. 0.0
// 1974 JAN 1 2442048.5 13.0 41317. 0.0
// 1975 JAN 1 2442413.5 14.0 41317. 0.0
// 1976 JAN 1 2442778.5 15.0 41317. 0.0
// 1977 JAN 1 2443144.5 16.0 41317. 0.0
// 1978 JAN 1 2443509.5 17.0 41317. 0.0
// month as a three letters upper case abbreviation
final
StringBuilder
builder
=
new
StringBuilder
(
BLANKS
+
STORAGE_START
);
for
(
final
Month
month
:
Month
.
values
())
{
builder
.
append
(
month
.
getUpperCaseAbbreviation
());
builder
.
append
(
ALTERNATIVE
);
}
builder
.
delete
(
builder
.
length
()
-
1
,
builder
.
length
());
builder
.
append
(
STORAGE_END
);
final
String
monthField
=
builder
.
toString
();
dataPattern
=
Pattern
.
compile
(
LINE_START_REGEXP
+
STORED_INTEGER_FIELD
+
monthField
+
STORED_INTEGER_FIELD
+
BLANKS
+
STORED_REAL_FIELD
+
BLANKS
+
STORED_REAL_FIELD
+
BLANKS
+
STORED_REAL_FIELD
+
BLANKS
+
STORED_REAL_FIELD
+
LINE_END_REGEXP
);
}
/** Load UTC-TAI offsets entries read from some file.
* <p>The time steps are extracted from some {@code LeapSecond.dat} file.
* Since entries are stored in a {@link java.util.SortedMap SortedMap},
* they are chronologically sorted and only one entry remains for a given date.</p>
* @param input data input stream
* @param name name of the file (or zip entry)
* @exception IOException if data can't be read
*/
@Override
public
List
<
OffsetModel
>
parse
(
final
InputStream
input
,
final
String
name
)
throws
IOException
{
final
List
<
OffsetModel
>
offsets
=
new
ArrayList
<>();
int
lineNumber
=
0
;
DateComponents
lastDate
=
null
;
String
line
=
null
;
// set up a reader for line-oriented file
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
input
,
StandardCharsets
.
UTF_8
)))
{
// read all file, ignoring not recognized lines
for
(
line
=
reader
.
readLine
();
line
!=
null
;
line
=
reader
.
readLine
())
{
++
lineNumber
;
// check matching for data lines
final
Matcher
matcher
=
dataPattern
.
matcher
(
line
);
if
(
matcher
.
matches
())
{
// build an entry from the extracted fields
final
DateComponents
dc1
=
new
DateComponents
(
Integer
.
parseInt
(
matcher
.
group
(
1
)),
Month
.
parseMonth
(
matcher
.
group
(
2
)),
Integer
.
parseInt
(
matcher
.
group
(
3
)));
final
DateComponents
dc2
=
new
DateComponents
(
DateComponents
.
JULIAN_EPOCH
,
(
int
)
FastMath
.
ceil
(
Double
.
parseDouble
(
matcher
.
group
(
4
))));
if
(!
dc1
.
equals
(
dc2
))
{
throw
new
OrekitException
(
OrekitMessages
.
INCONSISTENT_DATES_IN_IERS_FILE
,
name
,
dc1
.
getYear
(),
dc1
.
getMonth
(),
dc1
.
getDay
(),
dc2
.
getMJD
());
}
if
((
lastDate
!=
null
)
&&
dc1
.
compareTo
(
lastDate
)
<=
0
)
{
throw
new
OrekitException
(
OrekitMessages
.
NON_CHRONOLOGICAL_DATES_IN_FILE
,
name
,
lineNumber
);
}
lastDate
=
dc1
;
final
double
offset
=
Double
.
parseDouble
(
matcher
.
group
(
5
));
final
double
mjdRef
=
Double
.
parseDouble
(
matcher
.
group
(
6
));
final
double
slope
=
Double
.
parseDouble
(
matcher
.
group
(
7
));
offsets
.
add
(
new
OffsetModel
(
dc1
,
(
int
)
FastMath
.
rint
(
mjdRef
),
offset
,
slope
));
}
}
}
catch
(
NumberFormatException
nfe
)
{
throw
new
OrekitException
(
OrekitMessages
.
UNABLE_TO_PARSE_LINE_IN_FILE
,
lineNumber
,
name
,
line
);
}
if
(
offsets
.
isEmpty
())
{
throw
new
OrekitException
(
OrekitMessages
.
NO_ENTRIES_IN_IERS_UTC_TAI_HISTORY_FILE
,
name
);
}
return
offsets
;
}
}
}
src/test/java/org/orekit/time/AGILeapSecondFilesLoaderTest.java
0 → 100644
View file @
525d4d2a
/* Copyright 2002-2020 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.orekit.time
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
org.orekit.Utils
;
import
org.orekit.errors.OrekitException
;
import
org.orekit.errors.OrekitMessages
;
public
class
AGILeapSecondFilesLoaderTest
{
@Test
public
void
testRegularFile
()
{
Utils
.
setDataRoot
(
"AGI"
);
TimeScalesFactory
.
addUTCTAIOffsetsLoader
(
new
AGILeapSecondFilesLoader
(
AGILeapSecondFilesLoader
.
DEFAULT_SUPPORTED_NAMES
));
// we arbitrary put UTC == TAI before 1961-01-01
checkOffset
(
1950
,
1
,
1
,
0
);
// linear models between 1961 and 1972
checkOffset
(
1961
,
1
,
2
,
-(
1.422818
+
1
*
0.001296
));
// MJD 37300 + 1
checkOffset
(
1961
,
8
,
2
,
-(
1.372818
+
213
*
0.001296
));
// MJD 37300 + 213
checkOffset
(
1962
,
1
,
2
,
-(
1.845858
+
1
*
0.0011232
));
// MJD 37665 + 1
checkOffset
(
1963
,
11
,
2
,
-(
1.945858
+
670
*
0.0011232
));
// MJD 37665 + 670
checkOffset
(
1964
,
1
,
2
,
-(
3.240130
-
365
*
0.001296
));
// MJD 38761 - 365
checkOffset
(
1964
,
4
,
2
,
-(
3.340130
-
274
*
0.001296
));
// MJD 38761 - 274
checkOffset
(
1964
,
9
,
2
,
-(
3.440130
-
121
*
0.001296
));
// MJD 38761 - 121
checkOffset
(
1965
,
1
,
2
,
-(
3.540130
+
1
*
0.001296
));
// MJD 38761 + 1
checkOffset
(
1965
,
3
,
2
,
-(
3.640130
+
60
*
0.001296
));
// MJD 38761 + 60
checkOffset
(
1965
,
7
,
2
,
-(
3.740130
+
182
*
0.001296
));
// MJD 38761 + 182
checkOffset
(
1965
,
9
,
2
,
-(
3.840130
+
244
*
0.001296
));
// MJD 38761 + 244
checkOffset
(
1966
,
1
,
2
,
-(
4.313170
+
1
*
0.002592
));
// MJD 39126 + 1
checkOffset
(
1968
,
2
,
2
,
-(
4.213170
+
762
*
0.002592
));
// MJD 39126 + 762
// since 1972-01-01, offsets are only whole seconds
checkOffset
(
1972
,
3
,
5
,
-
10
);
checkOffset
(
1972
,
7
,
14
,
-
11
);
checkOffset
(
1979
,
12
,
31
,
-
18
);
checkOffset
(
1980
,
1
,
22
,
-
19
);
checkOffset
(
2006
,
7
,
7
,
-
33
);
checkOffset
(
2010
,
7
,
7
,
-
34
);
checkOffset
(
2012
,
7
,
7
,
-
35
);
checkOffset
(
2015
,
7
,
7
,
-
36
);
}
@Test
public
void
testInconsistentDate
()
{
checkException
(
"LeapSecond-inconsistent-date.dat"
,
OrekitMessages
.
INCONSISTENT_DATES_IN_IERS_FILE
);
}
@Test
public
void
testNonChronological
()
{
checkException
(
"LeapSecond-non-chronological.dat"
,
OrekitMessages
.
NON_CHRONOLOGICAL_DATES_IN_FILE
);
}
@Test
public
void
testFormatError
()
{
checkException
(
"LeapSecond-format-error.dat"
,
OrekitMessages
.
UNABLE_TO_PARSE_LINE_IN_FILE
);
}
private
void
checkOffset
(
int
year
,
int
month
,
int
day
,
double
offset
)
{
TimeScale
utc
=
TimeScalesFactory
.
getUTC
();
AbsoluteDate
date
=
new
AbsoluteDate
(
year
,
month
,
day
,
utc
);
Assert
.
assertEquals
(
offset
,
utc
.
offsetFromTAI
(
date
),
1.0
e
-
10
);
}
private
void
checkException
(
String
name
,
OrekitMessages
message
)
{
Utils
.
setDataRoot
(
"AGI"
);
TimeScalesFactory
.
addUTCTAIOffsetsLoader
(
new
AGILeapSecondFilesLoader
(
name
));
try
{
TimeScalesFactory
.
getUTC
();
Assert
.
fail
(
"an exception should have been thrown"
);
}
catch
(
OrekitException
oe
)
{
Assert
.
assertEquals
(
message
,
oe
.
getSpecifier
());
}
}
}
src/test/resources/AGI/LeapSecond-format-error.dat
0 → 100644
View file @
525d4d2a
28
1972 JAN 1 2441317.5 10.0 41317. 0.0
1972 JUL 1 2441499.5 11.0 41317. 0.0
1973 JAN 1 2441683.5 12.0 41317. 0.0
1974 JAN 1 2442048.5 13.0 41317. 0.0
1975 JAN 1 2442413.5 14.0 41317. 0.0
1976 JAN 1 2442778.5 15.0 41317. 0.0
1977 JAN 1 2443144.5 16.0 41317. 0.0
1978 JAN 1 2443509.5 17.0 41317. 0.0
1979 JAN 1 2443874.5 18.0 41317. 0.0
1980 JAN 1 2444239.5 19.0 41317. 0.0
1981 JUL 99999999999999999999999 2444786.5 20.0 41317. 0.0
1982 JUL 1 2445151.5 21.0 41317. 0.0
1983 JUL 1 2445516.5 22.0 41317. 0.0
1985 JUL 1 2446247.5 23.0 41317. 0.0
1988 JAN 1 2447161.5 24.0 41317. 0.0
1990 JAN 1 2447892.5 25.0 41317. 0.0
1991 JAN 1 2448257.5 26.0 41317. 0.0
1992 JUL 1 2448804.5 27.0 41317. 0.0
1993 JUL 1 2449169.5 28.0 41317. 0.0
1994 JUL 1 2449534.5 29.0 41317. 0.0
1996 JAN 1 2450083.5 30.0 41317. 0.0
1997 JUL 1 2450630.5 31.0 41317. 0.0
1999 JAN 1 2451179.5 32.0 41317. 0.0
2006 JAN 1 2453736.5 33.0 41317. 0.0
2009 JAN 1 2454832.5 34.0 41317. 0.0
2012 JUL 1 2456109.5 35.0 41317. 0.0
2015 JUL 1 2457204.5 36.0 41317. 0.0
2017 JAN 1 2457754.5 37.0 41317. 0.0
src/test/resources/AGI/LeapSecond-inconsistent-date.dat
0 → 100644
View file @
525d4d2a
28
1972 JAN 1 2441317.5 10.0 41317. 0.0
1972 AUG 1 2441499.5 11.0 41317. 0.0
1973 JAN 1 2441683.5 12.0 41317. 0.0
1974 JAN 1 2442048.5 13.0 41317. 0.0
1975 JAN 1 2442413.5 14.0 41317. 0.0
1976 JAN 1 2442778.5 15.0 41317. 0.0
1977 JAN 1 2443144.5 16.0 41317. 0.0
1978 JAN 1 2443509.5 17.0 41317. 0.0
1979 JAN 1 2443874.5 18.0 41317. 0.0
1980 JAN 1 2444239.5 19.0 41317. 0.0
1981 JUL 1 2444786.5 20.0 41317. 0.0
1982 JUL 1 2445151.5 21.0 41317. 0.0
1983 JUL 1 2445516.5 22.0 41317. 0.0
1985 JUL 1 2446247.5 23.0 41317. 0.0
1988 JAN 1 2447161.5 24.0 41317. 0.0
1990 JAN 1 2447892.5 25.0 41317. 0.0
1991 JAN 1 2448257.5 26.0 41317. 0.0
1992 JUL 1 2448804.5 27.0 41317. 0.0
1993 JUL 1 2449169.5 28.0 41317. 0.0
1994 JUL 1 2449534.5 29.0 41317. 0.0
1996 JAN 1 2450083.5 30.0 41317. 0.0
1997 JUL 1 2450630.5 31.0 41317. 0.0
1999 JAN 1 2451179.5 32.0 41317. 0.0
2006 JAN 1 2453736.5 33.0 41317. 0.0
2009 JAN 1 2454832.5 34.0 41317. 0.0
2012 JUL 1 2456109.5 35.0 41317. 0.0
2015 JUL 1 2457204.5 36.0 41317. 0.0
2017 JAN 1 2457754.5 37.0 41317. 0.0
src/test/resources/AGI/LeapSecond-non-chronological.dat
0 → 100644
View file @
525d4d2a
28
2017 JAN 1 2457754.5 37.0 41317. 0.0
2015 JUL 1 2457204.5 36.0 41317. 0.0
2012 JUL 1 2456109.5 35.0 41317. 0.0
2009 JAN 1 2454832.5 34.0 41317. 0.0
2006 JAN 1 2453736.5 33.0 41317. 0.0
1999 JAN 1 2451179.5 32.0 41317. 0.0
1997 JUL 1 2450630.5 31.0 41317. 0.0
1996 JAN 1 2450083.5 30.0 41317. 0.0
1994 JUL 1 2449534.5 29.0 41317. 0.0
1993 JUL 1 2449169.5 28.0 41317. 0.0
1992 JUL 1 2448804.5 27.0 41317. 0.0
1991 JAN 1 2448257.5 26.0 41317. 0.0
1990 JAN 1 2447892.5 25.0 41317. 0.0
1988 JAN 1 2447161.5 24.0 41317. 0.0
1985 JUL 1 2446247.5 23.0 41317. 0.0
1983 JUL 1 2445516.5 22.0 41317. 0.0
1982 JUL 1 2445151.5 21.0 41317. 0.0
1981 JUL 1 2444786.5 20.0 41317. 0.0
1980 JAN 1 2444239.5 19.0 41317. 0.0
1979 JAN 1 2443874.5 18.0 41317. 0.0
1978 JAN 1 2443509.5 17.0 41317. 0.0
1977 JAN 1 2443144.5 16.0 41317. 0.0
1976 JAN 1 2442778.5 15.0 41317. 0.0
1975 JAN 1 2442413.5 14.0 41317. 0.0
1974 JAN 1 2442048.5 13.0 41317. 0.0
1973 JAN 1 2441683.5 12.0 41317. 0.0
1972 JUL 1 2441499.5 11.0 41317. 0.0
1972 JAN 1 2441317.5 10.0 41317. 0.0
src/test/resources/AGI/LeapSecond.dat
0 → 100644
View file @
525d4d2a
28
1972 JAN 1 2441317.5 10.0 41317. 0.0
1972 JUL 1 2441499.5 11.0 41317. 0.0
1973 JAN 1 2441683.5 12.0 41317. 0.0
1974 JAN 1 2442048.5 13.0 41317. 0.0
1975 JAN 1 2442413.5 14.0 41317. 0.0
1976 JAN 1 2442778.5 15.0 41317. 0.0
1977 JAN 1 2443144.5 16.0 41317. 0.0
1978 JAN 1 2443509.5 17.0 41317. 0.0
1979 JAN 1 2443874.5 18.0 41317. 0.0
1980 JAN 1 2444239.5 19.0 41317. 0.0
1981 JUL 1 2444786.5 20.0 41317. 0.0
1982 JUL 1 2445151.5 21.0 41317. 0.0
1983 JUL 1 2445516.5 22.0 41317. 0.0
1985 JUL 1 2446247.5 23.0 41317. 0.0
1988 JAN 1 2447161.5 24.0 41317. 0.0
1990 JAN 1 2447892.5 25.0 41317. 0.0
1991 JAN 1 2448257.5 26.0 41317. 0.0
1992 JUL 1 2448804.5 27.0 41317. 0.0
1993 JUL 1 2449169.5 28.0 41317. 0.0
1994 JUL 1 2449534.5 29.0 41317. 0.0
1996 JAN 1 2450083.5 30.0 41317. 0.0
1997 JUL 1 2450630.5 31.0 41317. 0.0
1999 JAN 1 2451179.5 32.0 41317. 0.0
2006 JAN 1 2453736.5 33.0 41317. 0.0
2009 JAN 1 2454832.5 34.0 41317. 0.0
2012 JUL 1 2456109.5 35.0 41317. 0.0
2015 JUL 1 2457204.5 36.0 41317. 0.0
2017 JAN 1 2457754.5 37.0 41317. 0.0
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment