open-space-toolkit-physics 11.2.1__py313-none-manylinux2014_aarch64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. open_space_toolkit_physics-11.2.1.dist-info/METADATA +29 -0
  2. open_space_toolkit_physics-11.2.1.dist-info/RECORD +81 -0
  3. open_space_toolkit_physics-11.2.1.dist-info/WHEEL +5 -0
  4. open_space_toolkit_physics-11.2.1.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_physics-11.2.1.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/physics/OpenSpaceToolkitPhysicsPy.cpython-313-aarch64-linux-gnu.so +0 -0
  8. ostk/physics/__init__.py +6 -0
  9. ostk/physics/libopen-space-toolkit-physics.so.11 +0 -0
  10. ostk/physics/test/__init__.py +1 -0
  11. ostk/physics/test/coordinate/__init__.py +1 -0
  12. ostk/physics/test/coordinate/frame/__init__.py +1 -0
  13. ostk/physics/test/coordinate/frame/provider/__init__.py +1 -0
  14. ostk/physics/test/coordinate/frame/provider/iers/__init__.py +1 -0
  15. ostk/physics/test/coordinate/frame/provider/iers/conftest.py +38 -0
  16. ostk/physics/test/coordinate/frame/provider/iers/data/finals2000A.data +10953 -0
  17. ostk/physics/test/coordinate/frame/provider/iers/data/ser7.dat +524 -0
  18. ostk/physics/test/coordinate/frame/provider/iers/test_bulletin_a.py +108 -0
  19. ostk/physics/test/coordinate/frame/provider/iers/test_finals_2000a.py +93 -0
  20. ostk/physics/test/coordinate/frame/provider/iers/test_manager.py +205 -0
  21. ostk/physics/test/coordinate/spherical/__init__.py +1 -0
  22. ostk/physics/test/coordinate/spherical/test_aer.py +143 -0
  23. ostk/physics/test/coordinate/spherical/test_lla.py +490 -0
  24. ostk/physics/test/coordinate/test_axes.py +116 -0
  25. ostk/physics/test/coordinate/test_frame.py +107 -0
  26. ostk/physics/test/coordinate/test_position.py +206 -0
  27. ostk/physics/test/coordinate/test_transform.py +294 -0
  28. ostk/physics/test/coordinate/test_velocity.py +180 -0
  29. ostk/physics/test/data/conftest.py +34 -0
  30. ostk/physics/test/data/data/manifest.json +22 -0
  31. ostk/physics/test/data/provider/test_provider.py +34 -0
  32. ostk/physics/test/data/test_direction.py +40 -0
  33. ostk/physics/test/data/test_manifest.py +43 -0
  34. ostk/physics/test/data/test_manifest_manager.py +62 -0
  35. ostk/physics/test/data/test_scalar.py +54 -0
  36. ostk/physics/test/data/test_vector.py +70 -0
  37. ostk/physics/test/environment/__init__.py +1 -0
  38. ostk/physics/test/environment/atmospheric/__init__.py +1 -0
  39. ostk/physics/test/environment/atmospheric/earth/__init__.py +1 -0
  40. ostk/physics/test/environment/atmospheric/earth/conftest.py +67 -0
  41. ostk/physics/test/environment/atmospheric/earth/data/SW-Last5Years.test.csv +22 -0
  42. ostk/physics/test/environment/atmospheric/earth/data/SpaceWeather-All-v1.2.test.txt +811 -0
  43. ostk/physics/test/environment/atmospheric/earth/test_cssi_space_weather.py +126 -0
  44. ostk/physics/test/environment/atmospheric/earth/test_exponential.py +34 -0
  45. ostk/physics/test/environment/atmospheric/earth/test_manager.py +173 -0
  46. ostk/physics/test/environment/atmospheric/earth/test_nrlmsise00.py +34 -0
  47. ostk/physics/test/environment/atmospheric/test_earth.py +141 -0
  48. ostk/physics/test/environment/gravitational/__init__.py +1 -0
  49. ostk/physics/test/environment/gravitational/earth/__init__.py +1 -0
  50. ostk/physics/test/environment/gravitational/earth/test_manager.py +76 -0
  51. ostk/physics/test/environment/gravitational/test_earth.py +103 -0
  52. ostk/physics/test/environment/gravitational/test_moon.py +55 -0
  53. ostk/physics/test/environment/gravitational/test_spherical.py +36 -0
  54. ostk/physics/test/environment/gravitational/test_sun.py +53 -0
  55. ostk/physics/test/environment/magnetic/__init__.py +1 -0
  56. ostk/physics/test/environment/magnetic/earth/test_manager.py +64 -0
  57. ostk/physics/test/environment/magnetic/test_earth.py +38 -0
  58. ostk/physics/test/environment/object/__init__.py +1 -0
  59. ostk/physics/test/environment/object/celestial/__init__ .py +1 -0
  60. ostk/physics/test/environment/object/celestial/test_earth.py +174 -0
  61. ostk/physics/test/environment/object/celestial/test_moon.py +17 -0
  62. ostk/physics/test/environment/object/celestial/test_sun.py +17 -0
  63. ostk/physics/test/environment/object/test_celestial.py +12 -0
  64. ostk/physics/test/test_environment.py +97 -0
  65. ostk/physics/test/test_import.py +25 -0
  66. ostk/physics/test/time/__init__.py +1 -0
  67. ostk/physics/test/time/test_date.py +136 -0
  68. ostk/physics/test/time/test_date_time.py +230 -0
  69. ostk/physics/test/time/test_duration.py +215 -0
  70. ostk/physics/test/time/test_instant.py +103 -0
  71. ostk/physics/test/time/test_interval.py +432 -0
  72. ostk/physics/test/time/test_scale.py +11 -0
  73. ostk/physics/test/time/test_time.py +114 -0
  74. ostk/physics/test/unit/__init__.py +1 -0
  75. ostk/physics/test/unit/derived/__init__.py +1 -0
  76. ostk/physics/test/unit/derived/test_angle.py +368 -0
  77. ostk/physics/test/unit/test_derived.py +152 -0
  78. ostk/physics/test/unit/test_electric_current.py +5 -0
  79. ostk/physics/test/unit/test_length.py +297 -0
  80. ostk/physics/test/unit/test_mass.py +141 -0
  81. ostk/physics/test/unit/test_time.py +101 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "manifest": {
3
+ "path": "",
4
+ "filenames": "manifest.json",
5
+ "file_meta": "This file. Entry tracks the expected manifest update time on the github so that local OSTk can make smarter pulling decisions.",
6
+ "last_update": "2023-11-01T22:05:43.789048",
7
+ "next_update_check": "2023-11-02T04:05:43.789093",
8
+ "check_frequency": "6 hours"
9
+ },
10
+ "bulletin-A": {
11
+ "path": "coordinate/frame/providers/iers/bulletin-A",
12
+ "filenames": "ser7.dat",
13
+ "remote_sources": [
14
+ {
15
+ "url": "https://maia.usno.navy.mil/ser7/ser7.dat"
16
+ }
17
+ ],
18
+ "last_update": "2023-08-04T12:02:17.028701",
19
+ "next_update_check": "2023-08-05T12:02:17.029315",
20
+ "check_frequency": "1 day"
21
+ }
22
+ }
@@ -0,0 +1,34 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics import Environment
6
+ from ostk.physics.environment.object import Celestial
7
+ from ostk.physics.coordinate import Position
8
+ from ostk.physics.coordinate import Frame
9
+ from ostk.physics.data import provider
10
+
11
+
12
+ @pytest.fixture
13
+ def environment() -> Environment:
14
+ return Environment.default()
15
+
16
+
17
+ @pytest.fixture
18
+ def celestial(environment: Environment) -> Celestial:
19
+ return environment.access_celestial_object_with_name("Earth")
20
+
21
+
22
+ @pytest.fixture
23
+ def position():
24
+ return Position.meters([6671000.0, 0.0, 0.0], Frame.ITRF())
25
+
26
+
27
+ class TestProvider:
28
+ def test_nadir(
29
+ self,
30
+ celestial: Celestial,
31
+ position: Position,
32
+ environment: Environment,
33
+ ):
34
+ assert provider.nadir(position, celestial, environment) is not None
@@ -0,0 +1,40 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ from ostk.physics.data import Direction
8
+ from ostk.physics.coordinate import Frame
9
+
10
+
11
+ @pytest.fixture
12
+ def value() -> np.ndarray:
13
+ return np.array([1.0, 0.0, 0.0])
14
+
15
+
16
+ @pytest.fixture
17
+ def frame() -> Frame:
18
+ return Frame.GCRF()
19
+
20
+
21
+ @pytest.fixture
22
+ def direction(value: float, frame: Frame) -> Direction:
23
+ return Direction(
24
+ value=value,
25
+ frame=frame,
26
+ )
27
+
28
+
29
+ class TestDirection:
30
+ def test_constructor(self, direction: Direction):
31
+ assert direction is not None
32
+
33
+ def test_equals(self, direction: Direction):
34
+ assert direction == direction
35
+
36
+ def test_not_equals(self, direction: Direction):
37
+ assert (direction != direction) is False
38
+
39
+ def test_undefined(self):
40
+ assert Direction.undefined() is not None
@@ -0,0 +1,43 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+ from datetime import datetime
5
+
6
+ from ostk.core.filesystem import File
7
+ from ostk.core.filesystem import Path
8
+
9
+ from ostk.io import URL
10
+
11
+ from ostk.physics.data import Manifest
12
+ from ostk.physics.time import Instant
13
+
14
+
15
+ class TestManifest:
16
+ def test_is_defined_success(self, manifest: Manifest):
17
+ assert manifest.is_defined() == True
18
+
19
+ def test_get_last_modified_timestamp_success(self, manifest: Manifest):
20
+ assert isinstance(manifest.get_last_modified_timestamp(), Instant)
21
+
22
+ def test_get_last_update_timestamp_for_success(self, manifest: Manifest):
23
+ assert isinstance(manifest.get_last_update_timestamp_for("manifest"), Instant)
24
+
25
+ def test_get_next_update_check_timestamp_for_success(self, manifest: Manifest):
26
+ assert isinstance(
27
+ manifest.get_next_update_check_timestamp_for("manifest"), Instant
28
+ )
29
+
30
+ def test_get_remote_data_urls_success(self, manifest: Manifest):
31
+ test_url: URL = URL.parse("http://test.com")
32
+ assert isinstance(manifest.get_remote_data_urls(test_url, "manifest"), list)
33
+
34
+ def test_find_remote_data_urls_success(self, manifest: Manifest):
35
+ test_url: URL = URL.parse("http://test.com")
36
+ assert isinstance(manifest.find_remote_data_urls(test_url, ".*"), list)
37
+
38
+ def test_undefined_success(self):
39
+ assert isinstance(Manifest.undefined(), Manifest)
40
+
41
+ def test_load_success(self, manifest_file: File):
42
+ manifest = Manifest.load(manifest_file)
43
+ assert isinstance(manifest, Manifest)
@@ -0,0 +1,62 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+ from datetime import datetime
5
+ from ostk.core.filesystem import Directory
6
+ from ostk.core.filesystem import File
7
+ from ostk.core.filesystem import Path
8
+
9
+ from ostk.io import URL
10
+
11
+ from ostk.physics.time import Instant
12
+ from ostk.physics.data import Manager
13
+ from ostk.physics.data import Manifest
14
+
15
+
16
+ class TestManager:
17
+ def test_get_last_update_timestamp_for_success(self, manager: Manager):
18
+ assert isinstance(manager.get_last_update_timestamp_for("manifest"), Instant)
19
+
20
+ def test_get_remote_url_success(self, manager: Manager):
21
+ assert isinstance(manager.get_remote_url(), URL)
22
+
23
+ def test_get_local_repository_success(self, manager: Manager):
24
+ assert isinstance(manager.get_local_repository(), Directory)
25
+
26
+ def test_get_remote_data_urls_success(self, manager: Manager):
27
+ assert isinstance(manager.get_remote_data_urls("data_name"), list)
28
+
29
+ def test_get_manifest_success(self, manager: Manager):
30
+ assert isinstance(manager.get_manifest(), Manifest)
31
+
32
+ def test_set_remote_url_success(self, manager: Manager):
33
+ manager.set_remote_url(URL.parse("http://example.com"))
34
+ assert manager.get_remote_url() == URL.parse("http://example.com")
35
+
36
+ def test_set_local_repository_success(self, manager: Manager):
37
+ directory = Directory.path(Path.parse("./test_directory"))
38
+ manager.set_local_repository(directory)
39
+ assert manager.get_local_repository() == directory
40
+
41
+ def test_find_remote_data_urls_success(self, manager: Manager):
42
+ assert isinstance(manager.find_remote_data_urls(".*"), list)
43
+
44
+ def test_load_manifest_success(self, manager: Manager, manifest: Manifest):
45
+ manager.load_manifest(manifest)
46
+ assert manager.get_manifest().is_defined()
47
+
48
+ def test_manifest_file_exists_success(self, manager: Manager):
49
+ assert isinstance(manager.manifest_file_exists(), bool)
50
+
51
+ def test_reset_success(self, manager: Manager, manifest: Manifest):
52
+ manager.load_manifest(manifest)
53
+ assert manager.get_manifest().is_defined()
54
+
55
+ manager.reset()
56
+ assert not manager.get_manifest().is_defined()
57
+
58
+ def test_get_success(self):
59
+ assert isinstance(Manager.get(), Manager)
60
+
61
+ def test_default_remote_url_success(self, manager: Manager):
62
+ assert isinstance(manager.default_remote_url(), URL)
@@ -0,0 +1,54 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics import Unit
6
+ from ostk.physics.data import Scalar
7
+ from ostk.physics.unit import Length
8
+
9
+
10
+ @pytest.fixture
11
+ def unit() -> Unit:
12
+ return Unit.length(Length.Unit.Meter)
13
+
14
+
15
+ @pytest.fixture
16
+ def value() -> float:
17
+ return 5.0
18
+
19
+
20
+ @pytest.fixture
21
+ def scalar(value: float, unit: Unit) -> Scalar:
22
+ return Scalar(
23
+ value=value,
24
+ unit=unit,
25
+ )
26
+
27
+
28
+ class TestScalar:
29
+ def test_constructor(self, scalar: Scalar):
30
+ assert scalar is not None
31
+
32
+ def test_equals(self, scalar: Scalar):
33
+ assert scalar == scalar
34
+
35
+ def test_not_equals(self, scalar: Scalar):
36
+ assert (scalar != scalar) is False
37
+
38
+ def test_is_defined(self, scalar: Scalar):
39
+ assert scalar.is_defined()
40
+
41
+ def test_get_value(self, scalar: Scalar, value: float):
42
+ assert scalar.get_value() == value
43
+
44
+ def test_get_unit(self, scalar: Scalar):
45
+ assert scalar.get_unit().is_defined()
46
+
47
+ def test_in_unit(self, scalar: Scalar):
48
+ assert scalar.in_unit(Unit.length(Length.Unit.Foot)) is not None
49
+
50
+ def test_to_string(self, scalar: Scalar):
51
+ assert scalar.to_string() is not None
52
+
53
+ def test_undefined(self):
54
+ assert Scalar.undefined() is not None
@@ -0,0 +1,70 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ from ostk.physics import Unit
8
+ from ostk.physics.data import Vector
9
+ from ostk.physics.unit import Length
10
+ from ostk.physics.time import Instant
11
+ from ostk.physics.coordinate import Frame
12
+
13
+
14
+ @pytest.fixture
15
+ def unit() -> Unit:
16
+ return Unit.length(Length.Unit.Meter)
17
+
18
+
19
+ @pytest.fixture
20
+ def value() -> np.ndarray:
21
+ return np.array([1.0, 2.0, 3.0])
22
+
23
+
24
+ @pytest.fixture
25
+ def frame() -> Frame:
26
+ return Frame.GCRF()
27
+
28
+
29
+ @pytest.fixture
30
+ def vector(value: float, unit: Unit, frame: Frame) -> Vector:
31
+ return Vector(
32
+ value=value,
33
+ unit=unit,
34
+ frame=frame,
35
+ )
36
+
37
+
38
+ class TestVector:
39
+ def test_constructor(self, vector: Vector):
40
+ assert vector is not None
41
+
42
+ def test_equals(self, vector: Vector):
43
+ assert vector == vector
44
+
45
+ def test_not_equals(self, vector: Vector):
46
+ assert (vector != vector) is False
47
+
48
+ def test_is_defined(self, vector: Vector):
49
+ assert vector.is_defined()
50
+
51
+ def test_get_value(self, vector: Vector, value: float):
52
+ assert np.all(vector.get_value() == value)
53
+
54
+ def test_get_unit(self, vector: Vector):
55
+ assert vector.get_unit().is_defined()
56
+
57
+ def test_get_frame(self, vector: Vector, frame: Frame):
58
+ assert vector.get_frame() == frame
59
+
60
+ def test_in_unit(self, vector: Vector):
61
+ assert vector.in_unit(Unit.length(Length.Unit.Foot)) is not None
62
+
63
+ def test_in_frame(self, vector: Vector):
64
+ assert vector.in_frame(Frame.ITRF(), Instant.J2000()) is not None
65
+
66
+ def test_to_string(self, vector: Vector):
67
+ assert vector.to_string() is not None
68
+
69
+ def test_undefined(self):
70
+ assert Vector.undefined() is not None
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1,67 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import pathlib
6
+
7
+ from ostk.core.filesystem import Path
8
+ from ostk.core.filesystem import File
9
+
10
+ from ostk.io import URL
11
+
12
+ from ostk.physics.coordinate import Frame
13
+ from ostk.physics.environment.object.celestial import Sun
14
+ from ostk.physics.environment.atmospheric.earth import Manager
15
+ from ostk.physics.environment.atmospheric.earth import CSSISpaceWeather
16
+ from ostk.physics.environment.atmospheric.earth import Exponential
17
+ from ostk.physics.environment.atmospheric.earth import NRLMSISE00
18
+ from ostk.physics.environment.gravitational import Earth as EarthGravityModel
19
+
20
+
21
+ @pytest.fixture
22
+ def data_directory_path() -> str:
23
+ return f"{pathlib.Path(__file__).parent.absolute()}/data"
24
+
25
+
26
+ @pytest.fixture
27
+ def cssi_space_weather_file(data_directory_path: str) -> File:
28
+ return File.path(Path.parse(f"{data_directory_path}/SW-Last5Years.test.csv"))
29
+
30
+
31
+ @pytest.fixture
32
+ def cssi_space_weather_legacy_file(data_directory_path: str) -> File:
33
+ return File.path(Path.parse(f"{data_directory_path}/SpaceWeather-All-v1.2.test.txt"))
34
+
35
+
36
+ @pytest.fixture
37
+ def cssi_space_weather(cssi_space_weather_file: File) -> CSSISpaceWeather:
38
+ return CSSISpaceWeather.load(cssi_space_weather_file)
39
+
40
+
41
+ @pytest.fixture
42
+ def manager() -> Manager:
43
+ manager = Manager.get()
44
+
45
+ yield manager
46
+
47
+ manager.reset()
48
+ manager.clear_local_repository()
49
+
50
+
51
+ @pytest.fixture
52
+ def exponential_model() -> Exponential:
53
+ return Exponential()
54
+
55
+
56
+ @pytest.fixture
57
+ def nrlmsise00_model() -> NRLMSISE00:
58
+ return NRLMSISE00(
59
+ NRLMSISE00.InputDataType.CSSISpaceWeatherFile,
60
+ 160.0,
61
+ 160.0,
62
+ 3.0,
63
+ Frame.ITRF(),
64
+ EarthGravityModel.WGS84.equatorial_radius,
65
+ EarthGravityModel.WGS84.flattening,
66
+ Sun.spherical(),
67
+ )
@@ -0,0 +1,22 @@
1
+ DATE,BSRN,ND,KP1,KP2,KP3,KP4,KP5,KP6,KP7,KP8,KP_SUM,AP1,AP2,AP3,AP4,AP5,AP6,AP7,AP8,AP_AVG,CP,C9,ISN,F10.7_OBS,F10.7_ADJ,F10.7_DATA_TYPE,F10.7_OBS_CENTER81,F10.7_OBS_LAST81,F10.7_ADJ_CENTER81,F10.7_ADJ_LAST81
2
+ 2018-01-01,2515,21,33,37,23,23,27,10,10,13,177,18,22,9,9,12,4,4,5,10,0.6,3,0,69.1,66.8,OBS,71.4,72.5,69.3,70.8
3
+ 2018-01-02,2515,22,17,7,3,7,17,10,20,10,90,6,3,2,3,6,4,7,4,4,0.2,1,0,69.5,67.2,OBS,71.5,72.5,69.3,70.8
4
+ 2018-01-03,2515,23,0,7,10,7,3,10,3,0,40,0,3,4,3,2,4,2,0,2,0.0,0,0,70.7,68.3,INT,71.6,72.5,69.4,70.8
5
+ 2023-06-18,2589,17,27,20,13,20,17,17,27,20,160,12,7,5,7,6,6,12,7,8,0.4,2,159,164.1,169.4,OBS,160.4,152.8,165.2,155.5
6
+ 2023-06-19,2589,18,23,17,17,13,20,27,30,30,177,9,6,6,5,7,12,15,15,9,0.5,2,179,168.8,174.3,OBS,160.1,153.1,164.9,155.9
7
+
8
+ 2023-06-20,2589,19,27,20,10,17,20,23,10,40,167,12,7,4,6,7,9,4,27,9,0.5,2,203,164.6,170.0,PRD,160.2,153.6,165.0,156.4
9
+ 2023-06-21,2589,20,30,37,27,27,20,20,27,27,213,15,22,12,12,7,7,12,12,12,0.7,3,119,164.6,170.0,PRD,160.3,154.0,165.1,157.0
10
+ 2023-08-02,2591,8,13,13,13,13,13,13,13,13,104,5,5,5,5,5,5,5,5,5,0.2,1,123,165.0,170.0,PRD,157.5,160.8,162.0,165.7
11
+ 2023-08-03,2591,9,13,13,13,13,13,13,13,13,104,5,5,5,5,5,5,5,5,5,0.2,1,123,165.1,170.0,PRD,157.4,161.1,161.8,166.0
12
+
13
+ 2023-09-01,2592,11,,,,,,,,,,,,,,,,,,,,,124,151.3,154.2,PRM,154.2,158.3,156.9,163.1
14
+ 2023-10-01,2593,14,,,,,,,,,,,,,,,,,,,,,126,154.0,154.4,PRM,153.9,154.5,154.3,157.9
15
+ 2023-11-01,2594,18,,,,,,,,,,,,,,,,,,,,,128,156.6,154.3,PRM,156.4,153.1,154.3,154.2
16
+ 2023-12-01,2595,21,,,,,,,,,,,,,,,,,,,,,129,158.5,154.2,PRM,158.2,155.6,154.2,154.3
17
+ 2028-08-01,2658,25,,,,,,,,,,,,,,,,,,,,,45,82.7,85.2,PRM,83.3,84.3,85.6,86.9
18
+ 2028-09-01,2660,2,,,,,,,,,,,,,,,,,,,,,43,82.7,84.2,PRM,83.2,83.5,84.6,85.9
19
+ 2028-10-01,2661,5,,,,,,,,,,,,,,,,,,,,,41,82.9,83.1,PRM,83.5,83.2,83.6,85.0
20
+ 2028-11-01,2662,9,,,,,,,,,,,,,,,,,,,,,40,83.3,82.1,PRM,83.8,83.4,82.6,84.0
21
+ 2028-12-01,2663,12,,,,,,,,,,,,,,,,,,,,,38,83.7,81.4,PRM,83.9,83.7,81.8,83.0
22
+ 2029-01-01,2664,16,,,,,,,,,,,,,,,,,,,,,36,83.5,80.7,PRM,83.6,83.9,81.0,82.0