PCL
EphemerisFile.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.6.5
6 // ----------------------------------------------------------------------------
7 // pcl/EphemerisFile.h - Released 2024-01-13T15:47:58Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_EphemerisFile_h
53 #define __PCL_EphemerisFile_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/Atomic.h>
60 #include <pcl/AutoLock.h>
61 #include <pcl/AutoPointer.h>
62 #include <pcl/ChebyshevFit.h>
63 #include <pcl/File.h>
64 #include <pcl/Mutex.h>
65 #include <pcl/Optional.h>
66 #include <pcl/Thread.h>
67 #include <pcl/TimePoint.h>
68 
69 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
70 namespace pi
71 {
72  class JSEphemerisFileObject;
73  class JSEphemerisHandleObject;
74 }
75 #endif
76 
77 namespace pcl
78 {
79 
80 // ----------------------------------------------------------------------------
81 
82 class PCL_CLASS XMLElement;
83 
84 // ----------------------------------------------------------------------------
85 
103 struct PCL_CLASS EphemerisMetadata
104 {
114 };
115 
116 // ----------------------------------------------------------------------------
117 
133 struct PCL_CLASS EphemerisConstant
134 {
136  double value;
137 
141  EphemerisConstant( const IsoString& n = IsoString(), double v = 0 )
142  : name( n )
143  , value( v )
144  {
145  }
146 
150  EphemerisConstant( const EphemerisConstant& ) = default;
151 
155  EphemerisConstant( EphemerisConstant&& ) = default;
156 
160  EphemerisConstant& operator =( const EphemerisConstant& ) = default;
161 
165  EphemerisConstant& operator =( EphemerisConstant&& ) = default;
166 
171  bool operator ==( const EphemerisConstant& x ) const
172  {
173  return name.CompareIC( x.name ) == 0;
174  }
175 
181  bool operator <( const EphemerisConstant& x ) const
182  {
183  return name.CompareIC( x.name ) < 0;
184  }
185 };
186 
198 using EphemerisConstantList = Array<EphemerisConstant>;
199 
200 // ----------------------------------------------------------------------------
201 
223 {
229 
238 
243  : startTime( t )
244  , expansion( T )
245  {
246  }
247 
252 
257 
261  SerializableEphemerisData& operator =( const SerializableEphemerisData& ) = default;
262 
266  SerializableEphemerisData& operator =( SerializableEphemerisData&& ) = default;
267 };
268 
286 using SerializableEphemerisDataList = Array<SerializableEphemerisData>;
287 
288 // ----------------------------------------------------------------------------
289 
317 {
329 
345 
355 
361 
371 
372  /*
373  * Absolute magnitude. H is the visual magnitude of the object as seen at 1
374  * au of the Earth, 1 au from the Sun, and with a phase angle of 0 degrees.
375  *
376  * <b>References</b>
377  *
378  * E. Bowell et al., <em>Asteroids II</em>, R. P. Binzel et al. (eds.), The
379  * University of Arizona Press, Tucson, 1989, pp. 549-554.
380  *
381  * Urban, Sean E., Kenneth Seidelmann, P., ed. (2013), <em>The Explanatory
382  * Supplement to the Astronomical Almanac</em> 3rd Edition, Section 10.4.3.
383  */
385 
386  /*
387  * Slope parameter. See the H data member for references.
388  */
390 
391  /*
392  * Color index B-V in magnitudes.
393  */
394  Optional<double> B_V;
395 
396  /*
397  * Diameter of the object in km.
398  */
400 
405  const IsoString& origin,
406  const String& name = String(),
407  const String& desc = String() )
408  : objectId( id.Trimmed() )
409  , originId( origin.Trimmed() )
410  , objectName( name.Trimmed() )
411  , description( desc )
412  {
413  }
414 
419 
424 
429 
434 
439 };
440 
446 using SerializableEphemerisObjectDataList = Array<SerializableEphemerisObjectData>;
447 
448 // ----------------------------------------------------------------------------
449 
464 struct PCL_CLASS EphemerisObject
465 {
478 
492 
500 
505 
519 
524 
529 
534 
538  EphemerisObject( const IsoString& objectId_,
539  const IsoString& originId_,
540  const String& objectName_ = String(),
541  const String& objectDescription_ = String(),
546  : objectId( objectId_ )
547  , originId( originId_ )
548  , objectName( objectName_ )
549  , objectDescription( objectDescription_ )
550  , H( H_ )
551  , G( G_ )
552  , B_V( B_V_ )
553  , D( D_ )
554  {
555  }
556 
560  EphemerisObject( const EphemerisObject& ) = default;
561 
565  EphemerisObject( EphemerisObject&& ) = default;
566 
570  EphemerisObject& operator =( const EphemerisObject& ) = default;
571 
575  EphemerisObject& operator =( EphemerisObject&& ) = default;
576 };
577 
583 using EphemerisObjectList = Array<EphemerisObject>;
584 
585 // ----------------------------------------------------------------------------
586 
626 class PCL_CLASS EphemerisFile
627 {
628 public:
629 
636  EphemerisFile() = default;
637 
645  EphemerisFile( const String& filePath )
646  {
647  Open( filePath );
648  }
649 
654  : m_file( std::move( x.m_file ) )
655  , m_startTime( x.m_startTime )
656  , m_endTime( x.m_endTime )
657  , m_constants( std::move( x.m_constants ) )
658  , m_index( std::move( x.m_index ) )
659  {
660  }
661 
665  EphemerisFile& operator =( EphemerisFile&& x )
666  {
667  m_file = std::move( x.m_file );
668  m_startTime = x.m_startTime;
669  m_endTime = x.m_endTime;
670  m_constants = std::move( x.m_constants );
671  m_index = std::move( x.m_index );
672  return *this;
673  }
674 
679  EphemerisFile( const EphemerisFile& ) = delete;
680 
685  EphemerisFile& operator =( const EphemerisFile& ) = delete;
686 
690  virtual ~EphemerisFile() noexcept( false );
691 
709  void Open( const String& filePath );
710 
724  void Close();
725 
730  bool IsOpen() const
731  {
732  return m_file.IsOpen();
733  }
734 
739  const String& FilePath() const
740  {
741  return m_file.FilePath();
742  }
743 
750  {
751  return m_startTime;
752  }
753 
759  {
760  return m_endTime;
761  }
762 
776  {
777  return m_constants;
778  }
779 
784  bool IsConstantAvailable( const IsoString& name ) const
785  {
786  return BinarySearch( m_constants.Begin(), m_constants.End(),
787  EphemerisConstant( name ) ) != m_constants.End();
788  }
789 
797  double ConstantValue( const IsoString& name ) const
798  {
800  BinarySearch( m_constants.Begin(), m_constants.End(), EphemerisConstant( name ) );
801  if ( i == m_constants.End() )
802  throw Error( "Undefined ephemeris constant '" + name + '\'' );
803  return i->value;
804  }
805 
814  {
815  EphemerisObjectList objects;
816  for ( const Index& ix : m_index )
817  objects << EphemerisObject( ix.objectId, ix.originId,
818  ix.objectName, ix.objectDescription,
819  ix.H, ix.G, ix.B_V, ix.D );
820  return objects;
821  }
822 
846  bool IsObjectAvailable( const IsoString& object, const IsoString& origin = IsoString() ) const
847  {
848  Array<Index>::const_iterator i = BinarySearch( m_index.Begin(), m_index.End(), Index( object, origin ) );
849  if ( i != m_index.End() )
850  return true;
851  String name = object.UTF8ToUTF16();
852  for ( const Index& index : m_index )
853  if ( index.objectName.CompareIC( name ) == 0 )
854  if ( origin.IsEmpty() || index.originId == origin )
855  return true;
856  return false;
857  }
858 
872  String ObjectName( const IsoString& object, const IsoString& origin = IsoString() ) const
873  {
874  Array<Index>::const_iterator i = BinarySearch( m_index.Begin(), m_index.End(), Index( object, origin ) );
875  if ( i != m_index.End() )
876  return i->objectName;
877  return String();
878  }
879 
885  {
886  return m_metadata;
887  }
888 
901  int NumberOfHandles() const
902  {
903  return m_handleCount.Load();
904  }
905 
954  static void Serialize( const String& filePath,
955  TimePoint startTime, TimePoint endTime,
957  const EphemerisMetadata& metadata = EphemerisMetadata(),
958  const EphemerisConstantList& constants = EphemerisConstantList() );
959 
1008  static const EphemerisFile& FundamentalEphemerides();
1009 
1031  static const EphemerisFile& ShortTermFundamentalEphemerides();
1032 
1071  static const EphemerisFile& AsteroidEphemerides();
1072 
1094  static const EphemerisFile& ShortTermAsteroidEphemerides();
1095 
1150  static const EphemerisFile& KBOEphemerides();
1151 
1172  static const EphemerisFile& ShortTermKBOEphemerides();
1173 
1194  static const EphemerisFile& NutationModel();
1195 
1222  static const EphemerisFile& ShortTermNutationModel();
1223 
1259  static String DeltaTDataFilePath();
1260 
1283  static String DeltaATDataFilePath();
1284 
1301  static String CIP_ITRSDataFilePath();
1302 
1319  static void OverrideFundamentalEphemerides( const String& filePath );
1320 
1338  static void OverrideShortTermFundamentalEphemerides( const String& filePath );
1339 
1356  static void OverrideAsteroidEphemerides( const String& filePath );
1357 
1374  static void OverrideShortTermAsteroidEphemerides( const String& filePath );
1375 
1392  static void OverrideKBOEphemerides( const String& filePath );
1393 
1411  static void OverrideShortTermKBOEphemerides( const String& filePath );
1412 
1429  static void OverrideNutationModel( const String& filePath );
1430 
1448  static void OverrideShortTermNutationModel( const String& filePath );
1449 
1469  static void OverrideDeltaTDataFilePath( const String& filePath );
1470 
1490  static void OverrideDeltaATDataFilePath( const String& filePath );
1491 
1512  static void OverrideCIP_ITRSDataFilePath( const String& filePath );
1513 
1514 private:
1515 
1520  struct IndexNode
1521  {
1522  int32 jdi = 0; // Starting point of time span covered by this expansion, int( JD ).
1523  float jdf = 0; // Ditto, frac( JD ).
1524  uint8 n[ 4 ] = {}; // For each component: number of Chebyshev coefficients in this expansion.
1525  int64 position = 0; // File byte position of first Chebyshev coefficient.
1526 
1527  constexpr bool operator ==( const IndexNode& n ) const
1528  {
1529  return jdi == n.jdi && jdf == n.jdf;
1530  }
1531 
1532  constexpr bool operator <( const IndexNode& n ) const
1533  {
1534  return jdi < n.jdi || jdi == n.jdi && jdf < n.jdf;
1535  }
1536 
1537  constexpr int NumberOfComponents() const
1538  {
1539  return (n[0] > 0) ? ((n[1] > 0) ? ((n[2] > 0) ? ((n[3] > 0) ? 4 : 3) : 2) : 1) : 0;
1540  }
1541 
1542  constexpr int NumberOfCoefficients() const
1543  {
1544  return n[0] + n[1] + n[2] + n[3];
1545  }
1546 
1547  TimePoint StartTime() const
1548  {
1549  return TimePoint( jdi, jdf );
1550  }
1551  };
1552 
1557  struct Index
1558  {
1559  IsoString objectId; // Object identifier (mandatory, case-sensitive).
1560  IsoString originId; // Identifier of the origin of coordinates (mandatory, case-sensitive).
1561  String objectName; // Object name (optional, case-insensitive).
1562  String objectDescription; // Object description (optional, arbitrary)
1563  Optional<double> H; // Absolute magnitude.
1564  Optional<double> G; // Slope parameter.
1565  Optional<double> B_V; // Color index B-V in magnitudes.
1566  Optional<double> D; // Diameter of the object in km.
1567  Array<IndexNode> nodes[ 2 ]; // Expansion indexes: 0=function 1=derivative.
1568 
1569  Index( const IsoString& objectId_,
1570  const IsoString& originId_ = IsoString(),
1571  const String& objectName_ = String(),
1572  const String& objectDescription_ = String() )
1573  : objectId( objectId_.Trimmed() )
1574  , originId( originId_.Trimmed() )
1575  , objectName( objectName_.Trimmed() )
1576  , objectDescription( objectDescription_.Trimmed() )
1577  {
1578  }
1579 
1580  bool operator ==( const Index& x ) const
1581  {
1582  return objectId == x.objectId && originId == x.originId;
1583  }
1584 
1585  bool operator <( const Index& x ) const
1586  {
1587  return (objectId != x.objectId) ? objectId < x.objectId : originId < x.originId;
1588  }
1589 
1590  bool HasDerivative() const
1591  {
1592  return !nodes[1].IsEmpty();
1593  }
1594  };
1595 
1596  mutable File m_file;
1597  mutable AtomicInt m_handleCount;
1598  mutable Mutex m_mutex;
1599  TimePoint m_startTime;
1600  TimePoint m_endTime;
1601  EphemerisMetadata m_metadata;
1602  EphemerisConstantList m_constants;
1603  Array<Index> m_index;
1604 
1605  // Current data files.
1606  // If empty, i.e. if not overridden, use platform defaults.
1607  static String s_ephFilePath;
1608  static String s_ephFilePath_s;
1609  static String s_astFilePath;
1610  static String s_astFilePath_s;
1611  static String s_kboFilePath;
1612  static String s_kboFilePath_s;
1613  static String s_nutFilePath;
1614  static String s_nutFilePath_s;
1615  static String s_deltaTFilePath;
1616  static String s_deltaATFilePath;
1617  static String s_cipITRSFilePath;
1618 
1624  const Index* FindObject( const IsoString& object, const IsoString& origin ) const
1625  {
1626  if ( origin.IsEmpty() )
1627  {
1628  for ( const Index& index : m_index )
1629  if ( index.objectId == object )
1630  return &index;
1631  }
1632  else
1633  {
1634  Array<Index>::const_iterator i = BinarySearch( m_index.Begin(), m_index.End(), Index( object, origin ) );
1635  if ( i != m_index.End() )
1636  return i;
1637  }
1638  String name = object.UTF8ToUTF16();
1639  for ( const Index& index : m_index )
1640  if ( index.objectName.CompareIC( name ) == 0 )
1641  if ( origin.IsEmpty() || index.originId == origin )
1642  return &index;
1643  throw Error( "Unavailable object '" + name + "\' with origin '" + String( origin ) + "'." );
1644  }
1645 
1646 public:
1647 
1674  class PCL_CLASS Handle
1675  {
1676  public:
1677 
1704  Handle( const EphemerisFile& parent, const IsoString& object, const IsoString& origin = IsoString() )
1705  {
1706  if ( !parent.IsOpen() )
1707  throw Error( "Cannot create a handle to a closed ephemeris file." );
1708  m_parent = &parent;
1709  m_parent->m_handleCount.Increment();
1710  m_index = m_parent->FindObject( object, origin );
1711  }
1712 
1716  Handle( const Handle& x )
1717  {
1718  m_parent = x.m_parent;
1719  m_index = x.m_index;
1720  m_node[0] = x.m_node[0];
1721  m_node[1] = x.m_node[1];
1722  m_node[2] = x.m_node[2];
1723  if ( m_parent != nullptr )
1724  m_parent->m_handleCount.Increment();
1725  }
1726 
1731  {
1732  m_parent = x.m_parent;
1733  x.m_parent = nullptr;
1734  m_index = x.m_index;
1735  m_node[0] = x.m_node[0];
1736  m_node[1] = x.m_node[1];
1737  m_node[2] = x.m_node[2];
1738  }
1739 
1743  virtual ~Handle()
1744  {
1745  if ( m_parent != nullptr )
1746  m_parent->m_handleCount.Decrement();
1747  }
1748 
1752  Handle& operator =( const Handle& x )
1753  {
1754  if ( m_parent != nullptr )
1755  m_parent->m_handleCount.Decrement();
1756  m_parent = x.m_parent;
1757  m_index = x.m_index;
1758  m_node[0] = x.m_node[0];
1759  m_node[1] = x.m_node[1];
1760  m_node[2] = x.m_node[2];
1761  if ( m_parent != nullptr )
1762  m_parent->m_handleCount.Increment();
1763  return *this;
1764  }
1765 
1769  Handle& operator =( Handle&& x )
1770  {
1771  if ( m_parent != nullptr )
1772  m_parent->m_handleCount.Decrement();
1773  m_parent = x.m_parent;
1774  x.m_parent = nullptr;
1775  m_index = x.m_index;
1776  m_node[0] = x.m_node[0];
1777  m_node[1] = x.m_node[1];
1778  m_node[2] = x.m_node[2];
1779  return *this;
1780  }
1781 
1806  {
1807  Update( t, 0 );
1808  p = m_node[0].expansion( t - m_node[0].startTime );
1809  }
1810 
1847  {
1848  ComputeState( p, t );
1849  ComputeFirstDerivative( v, t );
1850  }
1851 
1883  {
1884  if ( HasDerivative() )
1885  Update( t, 1 );
1886  else if ( m_node[1].current != m_node[0].current )
1887  {
1888  m_node[1].current = m_node[0].current;
1889  m_node[1].startTime = m_node[0].startTime;
1890  m_node[1].endTime = m_node[0].endTime;
1891  m_node[1].expansion = m_node[0].expansion.Derivative();
1892  }
1893  v = m_node[1].expansion( t - m_node[1].startTime );
1894  }
1895 
1927  {
1928  if ( HasDerivative() )
1929  Update( t, 1 );
1930  else if ( m_node[1].current != m_node[0].current )
1931  {
1932  m_node[1].current = m_node[0].current;
1933  m_node[1].startTime = m_node[0].startTime;
1934  m_node[1].endTime = m_node[0].endTime;
1935  m_node[1].expansion = m_node[0].expansion.Derivative();
1936  }
1937  if ( m_node[2].current != m_node[0].current )
1938  {
1939  m_node[2].current = m_node[0].current;
1940  m_node[2].startTime = m_node[0].startTime;
1941  m_node[2].endTime = m_node[0].endTime;
1942  m_node[2].expansion = m_node[1].expansion.Derivative();
1943  }
1944  a = m_node[2].expansion( t - m_node[2].startTime );
1945  }
1946 
1959  {
1960  Vector p;
1961  ComputeState( p, t );
1962  return p;
1963  }
1964 
1980  {
1981  Vector p, v;
1982  ComputeState( p, v, t );
1983  return MultiVector( p, v );
1984  }
1985 
2000  {
2001  Vector v;
2002  ComputeFirstDerivative( v, t );
2003  return v;
2004  }
2005 
2020  {
2021  Vector v;
2022  ComputeSecondDerivative( v, t );
2023  return v;
2024  }
2025 
2030  const EphemerisFile& ParentFile() const
2031  {
2032  return *m_parent;
2033  }
2034 
2039  const IsoString& ObjectId() const
2040  {
2041  return m_index->objectId;
2042  }
2043 
2052  const IsoString& OriginId() const
2053  {
2054  return m_index->originId;
2055  }
2056 
2063  const String& ObjectName() const
2064  {
2065  return m_index->objectName;
2066  }
2067 
2078  TimePoint StartTime( int i = 0 ) const
2079  {
2080  return m_node[Range( i, 0, 1 )].startTime;
2081  }
2082 
2093  TimePoint EndTime( int i = 0 ) const
2094  {
2095  return m_node[Range( i, 0, 1 )].endTime;
2096  }
2097 
2107  bool HasDerivative() const
2108  {
2109  return m_index->HasDerivative();
2110  }
2111 
2126  const Optional<double>& H() const
2127  {
2128  return m_index->H;
2129  }
2130 
2134  const Optional<double>& G() const
2135  {
2136  return m_index->G;
2137  }
2138 
2142  const Optional<double>& B_V() const
2143  {
2144  return m_index->B_V;
2145  }
2146 
2151  const Optional<double>& D() const
2152  {
2153  return m_index->D;
2154  }
2155 
2156  private:
2157 
2158  struct NodeInfo
2159  {
2160  int current = -1;
2161  TimePoint startTime;
2162  TimePoint endTime;
2163  ChebyshevFit expansion;
2164  };
2165 
2166  const EphemerisFile* m_parent = nullptr;
2167  const EphemerisFile::Index* m_index = nullptr;
2168  NodeInfo m_node[ 3 ];
2169  uint64 m_uniqueId = UniqueId();
2170 
2171  static uint64 UniqueId();
2172 
2179  void Update( TimePoint t, int index )
2180  {
2181  if ( !t.IsValid() )
2182  throw Error( "Invalid time point." );
2183  if ( t < m_parent->StartTime() || t > m_parent->EndTime() )
2184  throw Error( "Time point out of range." );
2185 
2186  const Array<IndexNode>& nodes = m_index->nodes[index];
2187  NodeInfo& info = m_node[index];
2188 
2189  for ( int N = int( nodes.Length() ), l = 0, r = N-1; ; )
2190  {
2191  int m = (l + r) >> 1;
2192  const IndexNode& node = nodes[m];
2193  TimePoint t0 = node.StartTime();
2194  if ( t < t0 )
2195  r = m;
2196  else
2197  {
2198  if ( m == N-1 || t < nodes[m+1].StartTime() )
2199  {
2200  if ( m != info.current )
2201  {
2202  ChebyshevFit::coefficient_series coefficients;
2203  {
2204  volatile AutoLock lock( m_parent->m_mutex );
2205  m_parent->m_file.SetPosition( node.position );
2206  for ( int i = 0, n = node.NumberOfComponents(); i < n; ++i )
2207  {
2208  Vector c( node.n[i] );
2209  m_parent->m_file.Read( reinterpret_cast<void*>( c.Begin() ), c.Size() );
2210  coefficients << c;
2211  }
2212  }
2213  info.current = m;
2214  info.startTime = t0;
2215  info.endTime = (m < N-1) ? nodes[m+1].StartTime() : m_parent->EndTime();
2216  info.expansion = ChebyshevFit( coefficients, 0, info.endTime - info.startTime );
2217  }
2218  break;
2219  }
2220 
2221  l = m + 1;
2222  }
2223  }
2224  }
2225 
2226  friend class PCL_CLASS Position;
2227  };
2228 
2229 private:
2230 
2231 #if defined( __clang__ )
2232 # pragma GCC diagnostic ignored "-Wunused-private-field"
2233 #endif
2234 
2235  /*
2236  * For the core JavaScript engine we need garbage-collector-safe
2237  * asynchronous destruction of these objects.
2238  */
2239  mutable bool m_finalized = false;
2240 
2241  /*
2242  * In the core JavaScript engine we must identify static objects that can be
2243  * shared and must never be destroyed. This includes fundamental
2244  * ephemerides, nutation, etc.
2245  */
2246  mutable bool m_internal = false;
2247 
2248 #if defined( __clang__ )
2249 # pragma GCC diagnostic warning "-Wunused-private-field"
2250 #endif
2251 
2252  class DeserializeObjectThread : public Thread
2253  {
2254  public:
2255 
2256  DeserializeObjectThread( const Array<const XMLElement*>& elements
2257  , File& file, fsize_type fileSize, fsize_type minPos
2258  , int startIndex, int endIndex )
2259  : m_elements( elements )
2260  , m_startIndex( startIndex )
2261  , m_endIndex( endIndex )
2262  , m_file( file )
2263  , m_fileSize( fileSize )
2264  , m_minPos( minPos )
2265  {
2266  }
2267 
2268  void Run() override;
2269 
2270  const Array<Index>& Objects() const
2271  {
2272  return m_index;
2273  }
2274 
2275  bool Succeeded() const
2276  {
2277  return m_success;
2278  }
2279 
2280  const Exception* ExceptionThrown() const
2281  {
2282  return m_exception.Ptr();
2283  }
2284 
2285  private:
2286 
2287  const Array<const XMLElement*>& m_elements;
2288  int m_startIndex, m_endIndex;
2289  File& m_file;
2290  fsize_type m_fileSize, m_minPos;
2291  Array<Index> m_index;
2292  AutoPointer<Exception> m_exception;
2293  bool m_success = false;
2294  };
2295 
2296 #ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
2297  friend class pi::JSEphemerisFileObject;
2298  friend class pi::JSEphemerisHandleObject;
2299 #endif
2300 };
2301 
2302 // ----------------------------------------------------------------------------
2303 
2304 } // pcl
2305 
2306 #endif // __PCL_EphemerisFile_h
2307 
2308 // ----------------------------------------------------------------------------
2309 // EOF pcl/EphemerisFile.h - Released 2024-01-13T15:47:58Z
pcl::EphemerisFile::Handle::ObjectName
const String & ObjectName() const
Definition: EphemerisFile.h:2063
pcl::Array::Length
size_type Length() const noexcept
Definition: Array.h:266
pcl::SerializableEphemerisData::SerializableEphemerisData
SerializableEphemerisData(TimePoint t, const ChebyshevFit &T)
Definition: EphemerisFile.h:242
pcl
PCL root namespace.
Definition: AbstractImage.h:76
Atomic.h
Optional.h
pcl::Range
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
Definition: Utility.h:190
pcl::EphemerisFile::Handle::OriginId
const IsoString & OriginId() const
Definition: EphemerisFile.h:2052
pcl::EphemerisFile::NumberOfHandles
int NumberOfHandles() const
Definition: EphemerisFile.h:901
pcl::EphemerisMetadata::creatorOS
String creatorOS
The operating system on which this file was created.
Definition: EphemerisFile.h:106
pcl::EphemerisFile::ConstantValue
double ConstantValue(const IsoString &name) const
Definition: EphemerisFile.h:797
pcl::EphemerisMetadata::copyright
String copyright
Copyright information applicable to the data stored in this XEPH file.
Definition: EphemerisFile.h:113
pcl::EphemerisFile::ObjectName
String ObjectName(const IsoString &object, const IsoString &origin=IsoString()) const
Definition: EphemerisFile.h:872
pcl::EphemerisMetadata::description
String description
A full description of the data stored in this XEPH file.
Definition: EphemerisFile.h:110
pcl::Array< Index >::const_iterator
const Index * const_iterator
Definition: Array.h:117
TimePoint.h
pcl::String
Unicode (UTF-16) string.
Definition: String.h:8112
pcl::GenericString::CompareIC
int CompareIC(const GenericString< T, R1, A1 > &s, bool localeAware=true) const noexcept
Definition: String.h:3820
pcl::EphemerisFile::Handle::H
const Optional< double > & H() const
Definition: EphemerisFile.h:2126
pcl::operator==
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2090
pcl::EphemerisFile::Handle::ComputeState
void ComputeState(Vector &p, Vector &v, TimePoint t)
Definition: EphemerisFile.h:1846
pcl::EphemerisFile::Handle::ComputeSecondDerivative
void ComputeSecondDerivative(Vector &a, TimePoint t)
Definition: EphemerisFile.h:1926
pcl::Array::End
iterator End()
Definition: Array.h:451
pcl::IsoString
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5424
pcl::EphemerisConstant::name
IsoString name
The constant name (case-insensitive).
Definition: EphemerisFile.h:135
pcl::EphemerisFile::Handle::ComputeState
void ComputeState(Vector &p, TimePoint t)
Definition: EphemerisFile.h:1805
pcl::SerializableEphemerisObjectData::originId
IsoString originId
Definition: EphemerisFile.h:344
pcl::SerializableEphemerisObjectData::description
String description
Definition: EphemerisFile.h:360
pcl::EphemerisObject::objectName
String objectName
Definition: EphemerisFile.h:499
pcl::EphemerisFile::Handle::Handle
Handle(const EphemerisFile &parent, const IsoString &object, const IsoString &origin=IsoString())
Definition: EphemerisFile.h:1704
pcl::EphemerisMetadata::briefDescription
String briefDescription
A brief (single-line) description of this XEPH file.
Definition: EphemerisFile.h:109
pcl::EphemerisMetadata::authors
String authors
The names of one or more persons or groups that have created the data in this file.
Definition: EphemerisFile.h:112
pcl::EphemerisFile::IsConstantAvailable
bool IsConstantAvailable(const IsoString &name) const
Definition: EphemerisFile.h:784
pcl::EphemerisObject::originId
IsoString originId
Definition: EphemerisFile.h:491
pcl::EphemerisMetadata
Metadata items available in ephemeris files (XEPH format).
Definition: EphemerisFile.h:103
pcl::SerializableEphemerisObjectData::SerializableEphemerisObjectData
SerializableEphemerisObjectData(const IsoString &id, const IsoString &origin, const String &name=String(), const String &desc=String())
Definition: EphemerisFile.h:404
pcl::TimePoint::IsValid
constexpr bool IsValid() const
Definition: TimePoint.h:231
pcl::EphemerisFile::FilePath
const String & FilePath() const
Definition: EphemerisFile.h:739
pcl::EphemerisObject::G
Optional< double > G
Definition: EphemerisFile.h:523
pcl::EphemerisFile::Handle::StartTime
TimePoint StartTime(int i=0) const
Definition: EphemerisFile.h:2078
pcl::EphemerisObject::H
Optional< double > H
Definition: EphemerisFile.h:518
pcl::EphemerisObject
Identifiers and descriptive data of an object available in an ephemeris file.
Definition: EphemerisFile.h:464
pcl::EphemerisFile::Handle
Calculation of ephemerides from data stored in XEPH files.
Definition: EphemerisFile.h:1674
pcl::File::Read
virtual void Read(void *buffer, fsize_type len)
pcl::EphemerisFile::Constants
const EphemerisConstantList & Constants() const
Definition: EphemerisFile.h:775
pcl::EphemerisObject::EphemerisObject
EphemerisObject(const IsoString &objectId_, const IsoString &originId_, const String &objectName_=String(), const String &objectDescription_=String(), Optional< double > H_=Optional< double >(), Optional< double > G_=Optional< double >(), Optional< double > B_V_=Optional< double >(), Optional< double > D_=Optional< double >())
Definition: EphemerisFile.h:538
pcl::GenericString::IsEmpty
bool IsEmpty() const noexcept
Definition: String.h:818
pcl::EphemerisMetadata::creationTime
TimePoint creationTime
The date this file was created.
Definition: EphemerisFile.h:105
pcl::EphemerisFile::Handle::G
const Optional< double > & G() const
Definition: EphemerisFile.h:2134
pcl::Optional< double >
pcl::EphemerisFile::Handle::ParentFile
const EphemerisFile & ParentFile() const
Definition: EphemerisFile.h:2030
pcl::Error
A simple exception with an associated error message.
Definition: Exception.h:238
pcl::SerializableEphemerisData::startTime
TimePoint startTime
Definition: EphemerisFile.h:228
pcl::uint64
unsigned long long uint64
Definition: Defs.h:685
pcl::EphemerisMetadata::creatorApplication
String creatorApplication
The software application or program that created this file.
Definition: EphemerisFile.h:107
pcl::EphemerisFile::StartTime
TimePoint StartTime() const
Definition: EphemerisFile.h:749
pcl::TimePoint
An instant in any timescale.
Definition: TimePoint.h:102
EphemerisObjectList
Dynamic list of object identifiers and descriptions.
pcl::Array< SerializableEphemerisData >
pcl::uint8
unsigned char uint8
Definition: Defs.h:645
pcl::File::SetPosition
virtual void SetPosition(fpos_type pos)
SerializableEphemerisObjectDataList
Dynamic list of per-object data for ephemeris serialization.
pcl::EphemerisFile::Handle::ObjectId
const IsoString & ObjectId() const
Definition: EphemerisFile.h:2039
Thread.h
pcl::IsoString::UTF8ToUTF16
ustring_base UTF8ToUTF16(size_type i=0, size_type n=maxPos) const
Definition: String.h:12322
pcl::EphemerisObject::objectDescription
String objectDescription
Definition: EphemerisFile.h:504
pcl::EphemerisFile::Handle::EndTime
TimePoint EndTime(int i=0) const
Definition: EphemerisFile.h:2093
pcl::EphemerisFile::Handle::SecondDerivative
Vector SecondDerivative(TimePoint t)
Definition: EphemerisFile.h:2019
pcl::EphemerisFile::EndTime
TimePoint EndTime() const
Definition: EphemerisFile.h:758
pcl::EphemerisFile::IsObjectAvailable
bool IsObjectAvailable(const IsoString &object, const IsoString &origin=IsoString()) const
Definition: EphemerisFile.h:846
pcl::EphemerisFile::Handle::StateVectors
MultiVector StateVectors(TimePoint t)
Definition: EphemerisFile.h:1979
AutoPointer.h
ChebyshevFit
64-bit floating point Chebyshev function approximation.
pcl::EphemerisConstant
A numerical constant defined in an ephemeris file (XEPH format).
Definition: EphemerisFile.h:133
pcl::EphemerisMetadata::title
String title
A title that represents or identifies this XEPH file.
Definition: EphemerisFile.h:108
pcl::EphemerisMetadata::organizationName
String organizationName
The name of the organization responsible for this file.
Definition: EphemerisFile.h:111
pcl::GenericChebyshevFit
Approximation of vector-valued functions by Chebyshev polynomial expansions.
Definition: ChebyshevFit.h:101
pcl::SerializableEphemerisObjectData::objectId
IsoString objectId
Definition: EphemerisFile.h:328
pcl::EphemerisFile::Handle::D
const Optional< double > & D() const
Definition: EphemerisFile.h:2151
pcl::EphemerisFile
Solar system ephemerides from XEPH files.
Definition: EphemerisFile.h:626
pcl::EphemerisFile::Handle::B_V
const Optional< double > & B_V() const
Definition: EphemerisFile.h:2142
Mutex.h
pcl::SerializableEphemerisObjectData::objectName
String objectName
Definition: EphemerisFile.h:354
EphemerisConstantList
Dynamic list of ephemeris numerical constants.
pcl::EphemerisObject::objectId
IsoString objectId
Definition: EphemerisFile.h:477
pcl::fsize_type
int64 fsize_type
Definition: Defs.h:1188
pcl::EphemerisConstant::EphemerisConstant
EphemerisConstant(const IsoString &n=IsoString(), double v=0)
Definition: EphemerisFile.h:141
pcl::EphemerisFile::Handle::FirstDerivative
Vector FirstDerivative(TimePoint t)
Definition: EphemerisFile.h:1999
pcl::AutoLock
Automatic mutex lock/unlock.
Definition: AutoLock.h:83
pcl::int32
signed int int32
Definition: Defs.h:663
pcl::EphemerisFile::IsOpen
bool IsOpen() const
Definition: EphemerisFile.h:730
pcl::AtomicInt::Increment
void Increment()
Definition: Atomic.h:207
pcl::EphemerisFile::Metadata
const EphemerisMetadata & Metadata() const
Definition: EphemerisFile.h:884
pcl::EphemerisFile::Handle::Handle
Handle(const Handle &x)
Definition: EphemerisFile.h:1716
pcl::EphemerisFile::EphemerisFile
EphemerisFile(const String &filePath)
Definition: EphemerisFile.h:645
pcl::SerializableEphemerisObjectData
A set of Chebyshev polynomial expansions and associated ancillary data for ephemeris serialization.
Definition: EphemerisFile.h:316
pcl::BinarySearch
FI BinarySearch(FI i, FI j, const T &v) noexcept
Definition: Search.h:170
pcl::EphemerisConstant::value
double value
The constant value.
Definition: EphemerisFile.h:136
AutoLock.h
pcl::EphemerisFile::Objects
EphemerisObjectList Objects() const
Definition: EphemerisFile.h:813
pcl::SerializableEphemerisData
Chebyshev polynomial expansion coefficients for ephemeris serialization.
Definition: EphemerisFile.h:222
pcl::SerializableEphemerisData::expansion
ChebyshevFit expansion
Definition: EphemerisFile.h:237
pcl::GenericMultiVector
Generic array of vectors.
Definition: MultiVector.h:100
pcl::EphemerisFile::EphemerisFile
EphemerisFile(EphemerisFile &&x)
Definition: EphemerisFile.h:653
ChebyshevFit.h
pcl::EphemerisFile::Handle::StateVector
Vector StateVector(TimePoint t)
Definition: EphemerisFile.h:1958
pcl::int64
signed long long int64
Definition: Defs.h:679
Defs.h
pcl::EphemerisFile::Handle::ComputeFirstDerivative
void ComputeFirstDerivative(Vector &v, TimePoint t)
Definition: EphemerisFile.h:1882
pcl::EphemerisFile::Handle::HasDerivative
bool HasDerivative() const
Definition: EphemerisFile.h:2107
pcl::GenericVector< double >
File.h
pcl::EphemerisFile::Handle::~Handle
virtual ~Handle()
Definition: EphemerisFile.h:1743
pcl::EphemerisObject::B_V
Optional< double > B_V
Definition: EphemerisFile.h:528
pcl::EphemerisObject::D
Optional< double > D
Definition: EphemerisFile.h:533
pcl::EphemerisFile::Handle::Handle
Handle(Handle &&x)
Definition: EphemerisFile.h:1730
SerializableEphemerisDataList
Dynamic list of Chebyshev polynomial expansions for ephemeris serialization.
pcl::operator<
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2101