### NAME
Inpop - Calculate planet positions, lunar librations and time transformations using the high precision INPOP ephemeris.
### SYNOPSIS
Inpop is a Python package for calculating planetary positions using the very high precision INPOP ephemerides.
INPOP ephemerides are produced and published by IMCCE (https://ftp.imcce.fr/pub/ephem/planets/). Published INPOP files contain Chebyshev coefficients for the position of the solar system bodies as well as the libration angles of the moon.
Because the underlying models are based in general relativity, (most) INPOP files also contain time transformations. Since these depend on the positions of the solar system bodies, INPOP is a 4D ephemeris. INPOP files are available in the TCB or TDB timescales. TCB files contain the transformation TCG-TCB (TCGmTDB) and TDB files contain the transformation TT-TDB (TTmTDB). INPOP .dat files are published in big-endian and little-endian byte order and in both a -100 / +100 year time span and a -1000 / +1000 year time span. Files of the latter type typically do not support the time scale transformations needed for the very high precision applications. Inpop aims to support all INPOP binary (.dat) files.
#### REQUIREMENTS
Inpop depends on Numpy. Numba is not required but will result in a speedup when the file is loaded into memory.
#### PROVIDES
The inpop package provides a single class: Inpop. Besides positions, libration angles and time transformations it also computes the first order derivatives.
### DESCRIPTION
An Inpop constructor is called with a binary INPOP (.dat) file name as its argument:
```python
from inpop import Inpop
inpop = Inpop("inpop21a_TDB_m100_p100_tt.dat")
```
This will open the INPOP file. If the file is not found it will be downloaded automatically to the path given (if the path is writable). It is allowed to omit the filename completely, in this case the most recent 200 year TDB file is opened in the current working directory or, if not found, it is first downloaded to this location. Small INPOP files (-100 / +100 years) are loaded into memory for fast calculations, accelerated by just-in-time compilation through the LLVM compiler and Numba. If Numba is not available on the system the speedup by holding the file in memory will be significantly smaller.
It is possible to keep the data fully on disk and use seek operations to read the data into buffers:
```python
from inpop import Inpop
inpop = Inpop("inpop21a_TDB_m100_p100_tt.dat", load=False)
```
Similarly, large files (-1000 / +1000 years) can be forced into memory by specifying `load=True`.
Once the Inpop class is initiated we can inspect the time range for which the INPOP file has data:
```python
print(inpop.jd_beg, inpop.jd_end)
2414105.0 2488985.0
```
The time range is given in Julian days in the ephemeris time scale (TDB or TCB). The time scale of this file is TDB:
```python
print(inpop.timescale)
TDB
```
The following important constants are always present:
```python
print(inpop.AU, inpop.EMRAT)
149597870.7 81.30056789872074
```
Besides these constants INPOP files have a constant record which can be accessed through a dictionary:
```python
print(inpop.constants)
{'KSIZER': 1226.0, 'VERSIO': 21.1, 'FVERSI': 0.0, 'FORMAT': 11.0, 'UNITE': 1.0, 'TIMESC': 0.0, 'REDATE': 2021.0624, 'CLIGHT': 299792.458, 'GM_Mer': 4.91248045036476e-11, ...
```
The constant record contains up to 400 values used during the ephemeris integration:
```python
print(len(inpop.constants))
400
```
### The `info()` method
Further details about the internals of the file can be obtained through the `info` member function:
```
INPOP file inpop21a_TDB_m100_p100_tt.dat
Byte order Little-endian
Label ['INPOP21a', '', '']
JDbeg, JDend, interval 2414105.0, 2488985.0, 32.0
record_size 1226
num_const 400
AU, EMRAT 149597870.7, 81.30056789872074
DENUM 100
librat_ptr [819 10 4]
TTmTDB_ptr [939 12 8]
version 21.1
fversion 0.0
format 11.0
KSIZER 1226
UNITE 1
has_vel False
has_time True
has_asteroids False
unit_pos au
unit_vel au/day
unit_time s
unit_angle rad
timescale TDB
```
All of these are instance variables. As can be seen this file has a time conversion from TT to TDB (`has_time` is `True`) and units of position, velocity, time and angle are au, au/day, seconds and radians respectively. This is always the case, even if `UNITE == 0` (meaning file units are km and km/day). Units will be automatically converted to au and au/day.
#### `__str__()`
Above information can be obtained by:
```python
print(inpop)
```
#### `PV(jd, target, center, rate=True, **kwargs)`
This method computes the state of a solar system body (the target) with respect to a center at time jd. jd is the Julian date in the ephemeris time scale (TDB or TCB). Because of the limited precision of a `double` it is advised to split the Julian date in a day part and a time fraction if sub-millisecond accuracy is required. In that case jd should be a `np.array([date, time_fraction], dtype=np.double)` (in that order).
target and center are integers from 0 to 12. The state vectors are returned as a numpy array [P, V] of type np.double. P and V are both 3-vectors containing the position and velocity respectively. The encoding for the target and the center is as follows:
```
0 mercury
1 venus
2 earth
3 mars
4 jupiter
5 saturn
6 uranus
7 neptune
8 pluto
9 moon
10 sun
11 ssb
12 emb
```
If the above strings are passed to `PV` they will be converted automatically to the integer codes. For example, the position of the moon with respect to the earth on January 1 2000 at 12:00 TDB time was:
```python
print(inpop.PV(2451545.0, 'moon', 'earth'))
[[-0.0019492816590940113 -0.0017828919060276236 -0.0005087136946011068]
[ 0.0003716704750190104 -0.0003846978294553674 -0.0001740301567948636]]
```
The first row is the position in AU, the second row the velocity in AU/day. The distance between the moon and the earth at that moment was:
```python
import numpy as np
print(np.linalg.norm(inpop.PV(2451545.0, 'moon', 'earth')[0] * inpop.AU))
402448.639909165 # km`
```
If the velocity is not required it can be left out as follows:
```python
print(inpop.PV(2451545.0, 'moon', 'earth', rate=False))
[-0.0019492816590940113 -0.0017828919060276236 -0.0005087136946011068]
```
Because the INPOP file opened above contains TDB data (`self.timescale == "TDB"`), the result is given in the dynamical system. Note that there is a rate difference between TDB and TCB clocks and according to general relativity a scale difference occurs between the positions (and masses) as well. Although the correction is of order 1e-8 this falls well within the numerical and data precision of Inpop.
By passing the keyword argument `ts` it is possible to force the result in a specific timescale:
```python
print(np.linalg.norm(inpop.PV(2451545.0, 'moon', 'earth', rate=False, ts="TCB") * inpop.AU))
402448.2845950923 # km
```
As can be seen, there is a difference of 355.314 meters between these distances. The numerical precision for the earth-moon positions is in the 10 um range, much more precise than the available measurements, which are in the mm range.
Note that the TDB-TCB conversions degrade numerical accuracy somewhat, to the 1e-13 AU range for Pluto at 50 AU distance. For maximum accuracy it is advised to use INPOP ephemeris files for the time scale in which data is required.
#### `LBR(jd, rate=True)`
This method computes the physical libration angles of the moon. jd is again the Julian date in the ephemeris time scale. Note that since the earth and the moon rotate in the ICRF, the z-component winds linear in time with an oscillatory component superimposed. The angles are given in radians:
```python
print(inpop.LBR(2451545.0))
[[-5.4147737920634452e-02 4.2485576628776955e-01 7.1866746406895576e-01]
[-1.1684365616883440e-04 4.5189513573293875e-05 2.3009987407557086e-01]]
```
For increased time accuracy, again pass jd as `np.array([date, time_fraction], dtype=np.double)`. Like `PV`,`LBR` accepts the keyword argument `ts`.
#### `TTmTDB(tt_jd, rate=False)`
Time difference between the TT (terrestrial time) and TDB (barycentric dynamical time) scales, computed from the Julian date in TT. TT and TDB tick on average at the same rate but over the year there are relativistic drifts of the order of a millisecond. TDB = TT - TTmTDB(tt_jd). Given the small correction and the slow change the function can be used both ways. The correction is given in seconds.
```python
print(inpop.TTmTDB(2451545.0))
9.928893069898122e-05 # seconds
```
The accuracy of this result is better than 100ns for the past and next century.
For high precision, pass jd as a date and time array of length 2 (`np.array([date, time_fraction], dtype=np.double)`).
#### `TCGmTCB(tcg_jd, rate=False)`
Time difference between the TCB (barycentric coordinate time) and TCG (geocentric coordinate time) scales.
Again, for high precision, pass jd as a date/time array of length 2 (`np.array([date, time_fraction], dtype=np.double)`).
#### `close()`
Closes the INPOP file (if it was still open).
#### `__del__()`
Destructor, makes sure there are no dangling file pointers
#### A word about precision
Inpop is fully written in python and uses double precision arithmetic. When running tests against reference data the numerical errors are 2e-14 AU for positions and sub-us level for time over 2 centuries. If sub-ms precision is required, 2 floats should be used for the date. The first one can be used for pseudo-integer date arithmetic and the second one for the day fraction. The library will subtract day offsets from the first jd argument without error and then add the day fraction to a much smaller date, resulting in high precision calculations.
### AUTHOR
Inpop is written by Marcel Hesselberth.
### REPORTING BUGS
Inpop online help: https://github.com/hesselberth/Inpop/issues
### COPYRIGHT
Marcel Hesselberth.
1. Inpop is released under GPLv3. The text of the license can be found at https://www.gnu.org/licenses/gpl-3.0.txt .
This is free software: you are free to change and redistribute it. There is NO WARRANTY.
2. The software neither has any relation to IMCCE nor to Leiden University.
3. INPOP data and other files on the IMCCE web server are the intellectual property of the IMCCE. For their conditions of use, see https://www.imcce.fr/mentions-legales.
### SEE ALSO
CIP, CNAV and the documentation in inpop.py.
Raw data
{
"_id": null,
"home_page": null,
"name": "Inpop",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "astrometry, astronomy, celestial navigation, mathematics, physics",
"author": null,
"author_email": "Marcel Hesselberth <hessel@physics.leidenuniv.nl>",
"download_url": null,
"platform": null,
"description": "### NAME\nInpop - Calculate planet positions, lunar librations and time transformations using the high precision INPOP ephemeris.\n\n### SYNOPSIS\nInpop is a Python package for calculating planetary positions using the very high precision INPOP ephemerides.\nINPOP ephemerides are produced and published by IMCCE (https://ftp.imcce.fr/pub/ephem/planets/). Published INPOP files contain Chebyshev coefficients for the position of the solar system bodies as well as the libration angles of the moon.\n\nBecause the underlying models are based in general relativity, (most) INPOP files also contain time transformations. Since these depend on the positions of the solar system bodies, INPOP is a 4D ephemeris. INPOP files are available in the TCB or TDB timescales. TCB files contain the transformation TCG-TCB (TCGmTDB) and TDB files contain the transformation TT-TDB (TTmTDB). INPOP .dat files are published in big-endian and little-endian byte order and in both a -100 / +100 year time span and a -1000 / +1000 year time span. Files of the latter type typically do not support the time scale transformations needed for the very high precision applications. Inpop aims to support all INPOP binary (.dat) files.\n\n#### REQUIREMENTS\nInpop depends on Numpy. Numba is not required but will result in a speedup when the file is loaded into memory.\n\n#### PROVIDES\nThe inpop package provides a single class: Inpop. Besides positions, libration angles and time transformations it also computes the first order derivatives.\n\n### DESCRIPTION\nAn Inpop constructor is called with a binary INPOP (.dat) file name as its argument:\n\n```python\nfrom inpop import Inpop\ninpop = Inpop(\"inpop21a_TDB_m100_p100_tt.dat\")\n```\n\nThis will open the INPOP file. If the file is not found it will be downloaded automatically to the path given (if the path is writable). It is allowed to omit the filename completely, in this case the most recent 200 year TDB file is opened in the current working directory or, if not found, it is first downloaded to this location. Small INPOP files (-100 / +100 years) are loaded into memory for fast calculations, accelerated by just-in-time compilation through the LLVM compiler and Numba. If Numba is not available on the system the speedup by holding the file in memory will be significantly smaller.\n\nIt is possible to keep the data fully on disk and use seek operations to read the data into buffers:\n\n```python\nfrom inpop import Inpop\ninpop = Inpop(\"inpop21a_TDB_m100_p100_tt.dat\", load=False)\n```\n\nSimilarly, large files (-1000 / +1000 years) can be forced into memory by specifying `load=True`.\n\nOnce the Inpop class is initiated we can inspect the time range for which the INPOP file has data:\n\n```python\nprint(inpop.jd_beg, inpop.jd_end)\n2414105.0 2488985.0\n```\n\nThe time range is given in Julian days in the ephemeris time scale (TDB or TCB). The time scale of this file is TDB:\n\n```python\nprint(inpop.timescale)\nTDB\n```\n\nThe following important constants are always present:\n\n```python\nprint(inpop.AU, inpop.EMRAT)\n149597870.7 81.30056789872074\n```\n\nBesides these constants INPOP files have a constant record which can be accessed through a dictionary:\n\n```python\nprint(inpop.constants)\n{'KSIZER': 1226.0, 'VERSIO': 21.1, 'FVERSI': 0.0, 'FORMAT': 11.0, 'UNITE': 1.0, 'TIMESC': 0.0, 'REDATE': 2021.0624, 'CLIGHT': 299792.458, 'GM_Mer': 4.91248045036476e-11, ...\n```\n\nThe constant record contains up to 400 values used during the ephemeris integration:\n\n```python\nprint(len(inpop.constants))\n400\n```\n\n### The `info()` method\nFurther details about the internals of the file can be obtained through the `info` member function:\n\n```\nINPOP file inpop21a_TDB_m100_p100_tt.dat\nByte order Little-endian\nLabel ['INPOP21a', '', '']\nJDbeg, JDend, interval 2414105.0, 2488985.0, 32.0\nrecord_size 1226\nnum_const 400\nAU, EMRAT 149597870.7, 81.30056789872074\nDENUM 100\nlibrat_ptr [819 10 4]\nTTmTDB_ptr [939 12 8]\nversion 21.1\nfversion 0.0\nformat 11.0\nKSIZER 1226\nUNITE 1\nhas_vel False\nhas_time True\nhas_asteroids False\nunit_pos au\nunit_vel au/day\nunit_time s\nunit_angle rad\ntimescale TDB\n```\n\nAll of these are instance variables. As can be seen this file has a time conversion from TT to TDB (`has_time` is `True`) and units of position, velocity, time and angle are au, au/day, seconds and radians respectively. This is always the case, even if `UNITE == 0` (meaning file units are km and km/day). Units will be automatically converted to au and au/day.\n\n#### `__str__()`\n\nAbove information can be obtained by:\n\n```python\nprint(inpop)\n```\n\n#### `PV(jd, target, center, rate=True, **kwargs)`\nThis method computes the state of a solar system body (the target) with respect to a center at time jd. jd is the Julian date in the ephemeris time scale (TDB or TCB). Because of the limited precision of a `double` it is advised to split the Julian date in a day part and a time fraction if sub-millisecond accuracy is required. In that case jd should be a `np.array([date, time_fraction], dtype=np.double)` (in that order).\n\ntarget and center are integers from 0 to 12. The state vectors are returned as a numpy array [P, V] of type np.double. P and V are both 3-vectors containing the position and velocity respectively. The encoding for the target and the center is as follows:\n\n```\n 0 mercury\n 1 venus\n 2 earth\n 3 mars\n 4 jupiter\n 5 saturn\n 6 uranus\n 7 neptune\n 8 pluto\n 9 moon\n10 sun\n11 ssb\n12 emb\n```\n\nIf the above strings are passed to `PV` they will be converted automatically to the integer codes. For example, the position of the moon with respect to the earth on January 1 2000 at 12:00 TDB time was:\n\n```python\nprint(inpop.PV(2451545.0, 'moon', 'earth'))\n[[-0.0019492816590940113 -0.0017828919060276236 -0.0005087136946011068]\n [ 0.0003716704750190104 -0.0003846978294553674 -0.0001740301567948636]]\n```\n\nThe first row is the position in AU, the second row the velocity in AU/day. The distance between the moon and the earth at that moment was:\n\n```python\nimport numpy as np\nprint(np.linalg.norm(inpop.PV(2451545.0, 'moon', 'earth')[0] * inpop.AU))\n402448.639909165 # km`\n```\n\nIf the velocity is not required it can be left out as follows:\n```python\nprint(inpop.PV(2451545.0, 'moon', 'earth', rate=False))\n[-0.0019492816590940113 -0.0017828919060276236 -0.0005087136946011068]\n```\n\nBecause the INPOP file opened above contains TDB data (`self.timescale == \"TDB\"`), the result is given in the dynamical system. Note that there is a rate difference between TDB and TCB clocks and according to general relativity a scale difference occurs between the positions (and masses) as well. Although the correction is of order 1e-8 this falls well within the numerical and data precision of Inpop.\n\nBy passing the keyword argument `ts` it is possible to force the result in a specific timescale:\n\n```python\nprint(np.linalg.norm(inpop.PV(2451545.0, 'moon', 'earth', rate=False, ts=\"TCB\") * inpop.AU))\n402448.2845950923 # km\n```\n\nAs can be seen, there is a difference of 355.314 meters between these distances. The numerical precision for the earth-moon positions is in the 10 um range, much more precise than the available measurements, which are in the mm range.\n\nNote that the TDB-TCB conversions degrade numerical accuracy somewhat, to the 1e-13 AU range for Pluto at 50 AU distance. For maximum accuracy it is advised to use INPOP ephemeris files for the time scale in which data is required.\n\n#### `LBR(jd, rate=True)`\nThis method computes the physical libration angles of the moon. jd is again the Julian date in the ephemeris time scale. Note that since the earth and the moon rotate in the ICRF, the z-component winds linear in time with an oscillatory component superimposed. The angles are given in radians:\n\n```python\nprint(inpop.LBR(2451545.0))\n[[-5.4147737920634452e-02 4.2485576628776955e-01 7.1866746406895576e-01]\n [-1.1684365616883440e-04 4.5189513573293875e-05 2.3009987407557086e-01]]\n```\n\nFor increased time accuracy, again pass jd as `np.array([date, time_fraction], dtype=np.double)`. Like `PV`,`LBR` accepts the keyword argument `ts`.\n\n#### `TTmTDB(tt_jd, rate=False)`\nTime difference between the TT (terrestrial time) and TDB (barycentric dynamical time) scales, computed from the Julian date in TT. TT and TDB tick on average at the same rate but over the year there are relativistic drifts of the order of a millisecond. TDB = TT - TTmTDB(tt_jd). Given the small correction and the slow change the function can be used both ways. The correction is given in seconds.\n\n```python\nprint(inpop.TTmTDB(2451545.0))\n9.928893069898122e-05 # seconds\n```\n\nThe accuracy of this result is better than 100ns for the past and next century.\nFor high precision, pass jd as a date and time array of length 2 (`np.array([date, time_fraction], dtype=np.double)`).\n\n#### `TCGmTCB(tcg_jd, rate=False)`\nTime difference between the TCB (barycentric coordinate time) and TCG (geocentric coordinate time) scales.\nAgain, for high precision, pass jd as a date/time array of length 2 (`np.array([date, time_fraction], dtype=np.double)`).\n\n#### `close()`\nCloses the INPOP file (if it was still open).\n\n#### `__del__()`\nDestructor, makes sure there are no dangling file pointers\n\n#### A word about precision\nInpop is fully written in python and uses double precision arithmetic. When running tests against reference data the numerical errors are 2e-14 AU for positions and sub-us level for time over 2 centuries. If sub-ms precision is required, 2 floats should be used for the date. The first one can be used for pseudo-integer date arithmetic and the second one for the day fraction. The library will subtract day offsets from the first jd argument without error and then add the day fraction to a much smaller date, resulting in high precision calculations.\n\n### AUTHOR\nInpop is written by Marcel Hesselberth.\n\n### REPORTING BUGS\n Inpop online help: https://github.com/hesselberth/Inpop/issues\n\n### COPYRIGHT\nMarcel Hesselberth.\n\n1. Inpop is released under GPLv3. The text of the license can be found at https://www.gnu.org/licenses/gpl-3.0.txt .\n This is free software: you are free to change and redistribute it. There is NO WARRANTY.\n\n2. The software neither has any relation to IMCCE nor to Leiden University.\n\n3. INPOP data and other files on the IMCCE web server are the intellectual property of the IMCCE. For their conditions of use, see https://www.imcce.fr/mentions-legales.\n\n### SEE ALSO\nCIP, CNAV and the documentation in inpop.py.\n",
"bugtrack_url": null,
"license": null,
"summary": "Calculate planet positions, lunar librations and time transformations using the high precision INPOP epmemeris.",
"version": "0.5.3",
"project_urls": {
"Homepage": "https://github.com/hesselberth/Inpop",
"Issues": "https://github.com/hesselberth/Inpop/issues"
},
"split_keywords": [
"astrometry",
" astronomy",
" celestial navigation",
" mathematics",
" physics"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f1bde2490d1a030eba8dcffb6c695d7c9230b12b57c96f7f59951cea2fab7cd1",
"md5": "23574eee29a71ebe697b912261598d86",
"sha256": "3eabad9af2cd1a4b95038facdedf50c71cebc8e427ca43c3060f124ef24158ac"
},
"downloads": -1,
"filename": "inpop-0.5.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "23574eee29a71ebe697b912261598d86",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 27474,
"upload_time": "2025-01-10T23:01:23",
"upload_time_iso_8601": "2025-01-10T23:01:23.632563Z",
"url": "https://files.pythonhosted.org/packages/f1/bd/e2490d1a030eba8dcffb6c695d7c9230b12b57c96f7f59951cea2fab7cd1/inpop-0.5.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-10 23:01:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hesselberth",
"github_project": "Inpop",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "inpop"
}