52 #ifndef __PCL_EphemerisFile_h
53 #define __PCL_EphemerisFile_h
69 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
72 class JSEphemerisFileObject;
73 class JSEphemerisHandleObject;
82 class PCL_CLASS XMLElement;
483 : objectId( id.Trimmed() )
484 , originId( origin.Trimmed() )
485 , objectName( name.Trimmed() )
486 , description( desc )
707 : objectId( a_objectId )
708 , originId( a_originId )
709 , objectName( a_objectName )
710 , objectDescription( a_objectDescription )
826 : m_file( std::move( x.m_file ) )
827 , m_startTime( x.m_startTime )
828 , m_endTime( x.m_endTime )
829 , m_constants( std::move( x.m_constants ) )
830 , m_index( std::move( x.m_index ) )
839 m_file = std::move( x.m_file );
840 m_startTime = x.m_startTime;
841 m_endTime = x.m_endTime;
842 m_constants = std::move( x.m_constants );
843 m_index = std::move( x.m_index );
904 return m_file.IsOpen();
913 return m_file.FilePath();
958 return BinarySearch( m_constants.Begin(), m_constants.End(),
973 if ( i == m_constants.End() )
974 throw Error(
"Undefined ephemeris constant '" + name +
'\'' );
988 for (
const Index& ix : m_index )
990 ix.objectName, ix.objectDescription,
991 ix.H, ix.G, ix.M1, ix.K1, ix.M2, ix.K2, ix.PC, ix.B_V, ix.U_B, ix.I_R, ix.D,
992 ix.A1, ix.A2, ix.A3, ix.DT );
1003 for (
const Index& ix : m_index )
1015 for (
const Index& ix : m_index )
1016 names << ix.objectName;
1046 if ( i != m_index.
End() )
1049 for (
const Index& index : m_index )
1050 if ( index.objectName.CompareIC( name ) == 0 )
1051 if ( origin.
IsEmpty() || index.originId == origin )
1072 if ( i != m_index.
End() )
1073 return i->objectName;
1100 return m_handleCount.Load();
1730 constexpr
bool operator ==(
const IndexNode& n )
const
1732 return jdi == n.jdi && jdf == n.jdf;
1735 constexpr
bool operator <(
const IndexNode& n )
const
1737 return jdi < n.jdi || jdi == n.jdi && jdf < n.jdf;
1740 constexpr
int NumberOfComponents()
const
1742 return (n[0] > 0) ? ((n[1] > 0) ? ((n[2] > 0) ? ((n[3] > 0) ? 4 : 3) : 2) : 1) : 0;
1745 constexpr
int NumberOfCoefficients()
const
1747 return n[0] + n[1] + n[2] + n[3];
1750 TimePoint StartTime()
const
1752 return TimePoint( jdi, jdf );
1765 String objectDescription;
1768 Optional<double> M1;
1769 Optional<double> K1;
1770 Optional<double> M2;
1771 Optional<double> K2;
1772 Optional<double> PC;
1773 Optional<double> B_V;
1774 Optional<double> U_B;
1775 Optional<double> I_R;
1777 Optional<double> A1;
1778 Optional<double> A2;
1779 Optional<double> A3;
1780 Optional<double> DT;
1781 Array<IndexNode> nodes[ 2 ];
1783 Index(
const IsoString& objectId_,
1784 const IsoString& originId_ = IsoString(),
1785 const String& objectName_ = String(),
1786 const String& objectDescription_ = String() )
1787 : objectId( objectId_.Trimmed() )
1788 , originId( originId_.Trimmed() )
1789 , objectName( objectName_.Trimmed() )
1790 , objectDescription( objectDescription_.Trimmed() )
1796 return objectId == x.objectId && originId == x.originId;
1801 return (objectId != x.objectId) ? objectId < x.objectId : originId < x.originId;
1804 bool HasDerivative()
const
1806 return !nodes[1].IsEmpty();
1810 mutable File m_file;
1811 mutable AtomicInt m_handleCount;
1812 mutable Mutex m_mutex;
1813 TimePoint m_startTime;
1814 TimePoint m_endTime;
1815 EphemerisMetadata m_metadata;
1817 Array<Index> m_index;
1821 static String s_ephFilePath;
1822 static String s_ephFilePath_s;
1823 static String s_astFilePath;
1824 static String s_astFilePath_s;
1825 static String s_kboFilePath;
1826 static String s_kboFilePath_s;
1827 static String s_nutFilePath;
1828 static String s_nutFilePath_s;
1829 static String s_deltaTFilePath;
1830 static String s_deltaATFilePath;
1831 static String s_cipITRSFilePath;
1838 const Index* FindObject(
const IsoString&
object,
const IsoString& origin )
const
1840 if ( origin.IsEmpty() )
1842 for (
const Index& index : m_index )
1843 if ( index.objectId ==
object )
1849 if ( i != m_index.End() )
1853 for (
const Index& index : m_index )
1854 if ( index.objectName.CompareIC( name ) == 0 )
1855 if ( origin.IsEmpty() || index.originId == origin )
1857 throw Error(
"Unavailable object '" + name +
"\' with origin '" + String( origin ) +
"'." );
1927 throw Error(
"Cannot create a handle to a closed ephemeris file." );
1930 m_index = m_parent->FindObject(
object, origin );
1938 if ( m_parent !=
nullptr )
1939 m_parent->m_handleCount.Decrement();
1940 m_parent = x.m_parent;
1941 m_index = x.m_index;
1942 m_node[0] = x.m_node[0];
1943 m_node[1] = x.m_node[1];
1944 m_node[2] = x.m_node[2];
1945 if ( m_parent !=
nullptr )
1946 m_parent->m_handleCount.Increment();
1954 m_parent = x.m_parent;
1955 x.m_parent =
nullptr;
1956 m_index = x.m_index;
1957 m_node[0] = x.m_node[0];
1958 m_node[1] = x.m_node[1];
1959 m_node[2] = x.m_node[2];
1967 if ( m_parent !=
nullptr )
1968 m_parent->m_handleCount.Decrement();
1976 if ( m_parent !=
nullptr )
1977 m_parent->m_handleCount.Decrement();
1978 m_parent = x.m_parent;
1979 m_index = x.m_index;
1980 m_node[0] = x.m_node[0];
1981 m_node[1] = x.m_node[1];
1982 m_node[2] = x.m_node[2];
1983 if ( m_parent !=
nullptr )
1984 m_parent->m_handleCount.Increment();
1993 if ( m_parent !=
nullptr )
1994 m_parent->m_handleCount.Decrement();
1995 m_parent = x.m_parent;
1996 x.m_parent =
nullptr;
1997 m_index = x.m_index;
1998 m_node[0] = x.m_node[0];
1999 m_node[1] = x.m_node[1];
2000 m_node[2] = x.m_node[2];
2030 p = m_node[0].expansion( t - m_node[0].startTime );
2070 ComputeState( p, t );
2071 ComputeFirstDerivative( v, t );
2106 if ( HasDerivative() )
2108 else if ( m_node[1].current != m_node[0].current )
2110 m_node[1].current = m_node[0].current;
2111 m_node[1].startTime = m_node[0].startTime;
2112 m_node[1].endTime = m_node[0].endTime;
2113 m_node[1].expansion = m_node[0].expansion.Derivative();
2115 v = m_node[1].expansion( t - m_node[1].startTime );
2150 if ( HasDerivative() )
2152 else if ( m_node[1].current != m_node[0].current )
2154 m_node[1].current = m_node[0].current;
2155 m_node[1].startTime = m_node[0].startTime;
2156 m_node[1].endTime = m_node[0].endTime;
2157 m_node[1].expansion = m_node[0].expansion.Derivative();
2159 if ( m_node[2].current != m_node[0].current )
2161 m_node[2].current = m_node[0].current;
2162 m_node[2].startTime = m_node[0].startTime;
2163 m_node[2].endTime = m_node[0].endTime;
2164 m_node[2].expansion = m_node[1].expansion.Derivative();
2166 a = m_node[2].expansion( t - m_node[2].startTime );
2183 ComputeState( p, t );
2204 ComputeState( p, v, t );
2224 ComputeFirstDerivative( v, t );
2244 ComputeSecondDerivative( v, t );
2263 return m_index->objectId;
2276 return m_index->originId;
2287 return m_index->objectName;
2302 return m_node[
Range( i, 0, 1 )].startTime;
2317 return m_node[
Range( i, 0, 1 )].endTime;
2331 return m_index->HasDerivative();
2427 return m_index->B_V;
2435 return m_index->U_B;
2443 return m_index->I_R;
2502 const EphemerisFile::Index* m_index =
nullptr;
2503 NodeInfo m_node[ 3 ];
2504 uint64 m_uniqueId = UniqueId();
2506 static uint64 UniqueId();
2517 throw Error(
"Invalid time point." );
2518 if ( t < m_parent->StartTime() || t > m_parent->
EndTime() )
2522 NodeInfo& info = m_node[index];
2524 for (
int N =
int( nodes.
Length() ), l = 0, r = N-1; ; )
2526 int m = (l + r) >> 1;
2527 const IndexNode& node = nodes[m];
2533 if ( m == N-1 || t < nodes[m+1].StartTime() )
2535 if ( m != info.current )
2539 volatile AutoLock lock( m_parent->m_mutex );
2541 for (
int i = 0, n = node.NumberOfComponents(); i < n; ++i )
2544 m_parent->m_file.
Read(
reinterpret_cast<void*
>( c.Begin() ), c.Size() );
2549 info.startTime = t0;
2550 info.endTime = (m < N-1) ? nodes[m+1].StartTime() : m_parent->
EndTime();
2551 info.expansion =
ChebyshevFit( coefficients, 0, info.endTime - info.startTime );
2561 friend class PCL_CLASS Position;
2566 #if defined( __clang__ )
2567 # pragma GCC diagnostic ignored "-Wunused-private-field"
2574 mutable bool m_finalized =
false;
2581 mutable bool m_internal =
false;
2583 #if defined( __clang__ )
2584 # pragma GCC diagnostic warning "-Wunused-private-field"
2587 class DeserializeObjectThread :
public Thread
2591 DeserializeObjectThread(
const Array<const XMLElement*>& elements
2593 ,
int startIndex,
int endIndex )
2594 : m_elements( elements )
2595 , m_startIndex( startIndex )
2596 , m_endIndex( endIndex )
2598 , m_fileSize( fileSize )
2599 , m_minPos( minPos )
2603 void Run()
override;
2605 const Array<Index>& Objects()
const
2610 bool Succeeded()
const
2615 const Exception* ExceptionThrown()
const
2617 return m_exception.Ptr();
2622 const Array<const XMLElement*>& m_elements;
2623 int m_startIndex, m_endIndex;
2626 Array<Index> m_index;
2627 AutoPointer<Exception> m_exception;
2628 bool m_success =
false;
2631 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
2632 friend class pi::JSEphemerisFileObject;
2633 friend class pi::JSEphemerisHandleObject;
size_type Length() const noexcept
const Index * const_iterator
Automatic mutex lock/unlock.
64-bit floating point Chebyshev function approximation.
Dynamic list of ephemeris numerical constants.
Calculation of ephemerides from data stored in XEPH files.
const Optional< double > & M2() const
const Optional< double > & U_B() const
TimePoint EndTime(int i=0) const
MultiVector StateVectors(TimePoint t)
const Optional< double > & A1() const
void ComputeState(Vector &p, TimePoint t)
const Optional< double > & DT() const
const Optional< double > & B_V() const
const IsoString & ObjectId() const
const Optional< double > & A2() const
void ComputeState(Vector &p, Vector &v, TimePoint t)
Handle(const EphemerisFile &parent, const IsoString &object, const IsoString &origin=IsoString())
const Optional< double > & M1() const
Vector FirstDerivative(TimePoint t)
const Optional< double > & I_R() const
const Optional< double > & D() const
const Optional< double > & PC() const
const Optional< double > & K2() const
const Optional< double > & G() const
const EphemerisFile & ParentFile() const
Vector SecondDerivative(TimePoint t)
void ComputeFirstDerivative(Vector &v, TimePoint t)
const String & ObjectName() const
bool HasDerivative() const
const Optional< double > & A3() const
const IsoString & OriginId() const
const Optional< double > & K1() const
TimePoint StartTime(int i=0) const
Vector StateVector(TimePoint t)
void ComputeSecondDerivative(Vector &a, TimePoint t)
const Optional< double > & H() const
Solar system ephemerides from XEPH files.
static void OverrideAsteroidEphemerides(const String &filePath)
const EphemerisMetadata & Metadata() const
static void Serialize(const String &filePath, TimePoint startTime, TimePoint endTime, const SerializableEphemerisObjectDataList &data, const EphemerisMetadata &metadata=EphemerisMetadata(), const EphemerisConstantList &constants=EphemerisConstantList())
StringList ObjectNames() const
static String CIP_ITRSDataFilePath()
IsoStringList ObjectIds() const
TimePoint StartTime() const
static const EphemerisFile & FundamentalEphemerides()
EphemerisObjectList Objects() const
EphemerisFile(EphemerisFile &&x)
int NumberOfHandles() const
EphemerisFile(const String &filePath)
static const EphemerisFile & ShortTermKBOEphemerides()
static const EphemerisFile & ShortTermFundamentalEphemerides()
static void OverrideNutationModel(const String &filePath)
static void OverrideCIP_ITRSDataFilePath(const String &filePath)
static const EphemerisFile & NutationModel()
bool IsConstantAvailable(const IsoString &name) const
static void OverrideFundamentalEphemerides(const String &filePath)
static const EphemerisFile & AsteroidEphemerides()
static const EphemerisFile & KBOEphemerides()
const String & FilePath() const
String ObjectName(const IsoString &object, const IsoString &origin=IsoString()) const
static void OverrideShortTermKBOEphemerides(const String &filePath)
double ConstantValue(const IsoString &name) const
static void OverrideShortTermAsteroidEphemerides(const String &filePath)
static String DeltaTDataFilePath()
virtual ~EphemerisFile() noexcept(false)
static void OverrideShortTermNutationModel(const String &filePath)
static const EphemerisFile & ShortTermNutationModel()
bool IsObjectAvailable(const IsoString &object, const IsoString &origin=IsoString()) const
EphemerisFile(const EphemerisFile &)=delete
static String DeltaATDataFilePath()
static void OverrideShortTermFundamentalEphemerides(const String &filePath)
TimePoint EndTime() const
static void OverrideDeltaATDataFilePath(const String &filePath)
const EphemerisConstantList & Constants() const
static void OverrideKBOEphemerides(const String &filePath)
static const EphemerisFile & ShortTermAsteroidEphemerides()
static void OverrideDeltaTDataFilePath(const String &filePath)
A simple exception with an associated error message.
virtual void Read(void *buffer, fsize_type len)
virtual void SetPosition(fpos_type pos)
Approximation of vector-valued functions by Chebyshev polynomial expansions.
Generic array of vectors.
bool IsEmpty() const noexcept
int CompareIC(const GenericString< T, R1, A1 > &s, bool localeAware=true) const noexcept
Generic vector of arbitrary length.
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
ustring_base UTF8ToUTF16(size_type i=0, size_type n=maxPos) const
An instant in any timescale.
String ToString(const ISO8601ConversionOptions &options=ISO8601ConversionOptions(), double tz=0) const
constexpr bool IsValid() const
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
unsigned long long uint64
FI BinarySearch(FI i, FI j, const T &v) noexcept
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
A numerical constant defined in an ephemeris file (XEPH format).
double value
The constant value.
EphemerisConstant(const EphemerisConstant &)=default
IsoString name
The constant name (case-insensitive).
EphemerisConstant(EphemerisConstant &&)=default
EphemerisConstant(const IsoString &n=IsoString(), double v=0)
Identifiers and descriptive data of an object available in an ephemeris file.
EphemerisObject(const EphemerisObject &)=default
EphemerisObject(const IsoString &a_objectId, const IsoString &a_originId, const String &a_objectName=String(), const String &a_objectDescription=String(), Optional< double > a_H=Optional< double >(), Optional< double > a_G=Optional< double >(), Optional< double > a_M1=Optional< double >(), Optional< double > a_K1=Optional< double >(), Optional< double > a_M2=Optional< double >(), Optional< double > a_K2=Optional< double >(), Optional< double > a_PC=Optional< double >(), Optional< double > a_B_V=Optional< double >(), Optional< double > a_U_B=Optional< double >(), Optional< double > a_I_R=Optional< double >(), Optional< double > a_D=Optional< double >(), Optional< double > a_A1=Optional< double >(), Optional< double > a_A2=Optional< double >(), Optional< double > a_A3=Optional< double >(), Optional< double > a_DT=Optional< double >())
EphemerisObject(EphemerisObject &&)=default
Chebyshev polynomial expansion coefficients for ephemeris serialization.
SerializableEphemerisData(SerializableEphemerisData &&)=default
SerializableEphemerisData(TimePoint t, const ChebyshevFit &T)
SerializableEphemerisData(const SerializableEphemerisData &)=default
A set of Chebyshev polynomial expansions and associated ancillary data for ephemeris serialization.
SerializableEphemerisObjectData(SerializableEphemerisObjectData &&)=default
SerializableEphemerisObjectData(const IsoString &id, const IsoString &origin, const String &name=String(), const String &desc=String())
SerializableEphemerisObjectData(const SerializableEphemerisObjectData &)=default
SerializableEphemerisObjectData()=default