diff --git a/README.md b/README.md index 6d2fa6f..5852afd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,6 @@ 1. Navigate to the relevant folder where the Python bindings are installed, e.g. `/home/$USER/Workspace/nyx-space/anise/anise-py` 2. Install `pdoc3` with pipx if not available yet: `pipx install pdoc3` 3. Run pdoc with the `--pdf` flag, which generates a markdown actually: `pdoc3 anise.astro --pdf > /home/$USER/Workspace/nyx-space/docs/docs/anise/reference/api/python/astro2.md`. Keep in mind that there are TWO `docs` folders here! -4. This will create a mostly ready Markdown, but you'll need to clean it up by removing all occurrence of ` {#id}` (search and replace with nothing) and then removing extra new lines with `sed`: `sed '/^$/N;/\n$/D' /home/$USER/Workspace/nyx-space/docs/docs/anise/reference/api/python/astro/index2.md > /home/$USER/Workspace/nyx-space/docs/docs/anise/reference/api/python/astro/index.md`. **Importantly**, you must specify a different output than input or the file will be empty. +4. This will create a mostly ready Markdown, but remove extra new lines with `sed`: `sed '/^$/N;/\n$/D' /home/$USER/Workspace/nyx-space/docs/docs/anise/reference/api/python/astro/index2.md > /home/$USER/Workspace/nyx-space/docs/docs/anise/reference/api/python/astro/index.md`. **Importantly**, you must specify a different output than input or the file will be empty. -A few manual edits are typically required. Check on the staging server first. \ No newline at end of file +A few manual edits are typically required. Check on the staging server first. diff --git a/docs/anise/reference/api/python/astro.md b/docs/anise/reference/api/python/astro.md new file mode 100644 index 0000000..898d9f1 --- /dev/null +++ b/docs/anise/reference/api/python/astro.md @@ -0,0 +1,2385 @@ +# Module `anise.astro` {#anise.astro} + + +## Sub-modules + +* [anise.astro.constants](#anise.astro.constants) + + +## Classes + + +### Class `AzElRange` {#anise.astro.AzElRange} + +> class AzElRange( +> epoch, +> azimuth_deg, +> elevation_deg, +> range_km, +> range_rate_km_s, +> obstructed_by=None +> ) + +A structure that stores the result of Azimuth, Elevation, Range, Range rate calculation. + +:type epoch: Epoch +:type azimuth_deg: float +:type elevation_deg: float +:type range_km: float +:type range_rate_km_s: float +:type obstructed_by: Frame, optional +:rtype: AzElRange + + +#### Instance variables + + +##### Variable `azimuth_deg` {#anise.astro.AzElRange.azimuth_deg} + +:rtype: float + + +##### Variable `elevation_deg` {#anise.astro.AzElRange.elevation_deg} + +:rtype: float + + +##### Variable `epoch` {#anise.astro.AzElRange.epoch} + +:rtype: Epoch + + +##### Variable `light_time` {#anise.astro.AzElRange.light_time} + +:rtype: Duration + + +##### Variable `obstructed_by` {#anise.astro.AzElRange.obstructed_by} + +:rtype: Frame + + +##### Variable `range_km` {#anise.astro.AzElRange.range_km} + +:rtype: float + + +##### Variable `range_rate_km_s` {#anise.astro.AzElRange.range_rate_km_s} + +:rtype: float + + +#### Methods + + +##### Method `is_obstructed` {#anise.astro.AzElRange.is_obstructed} + +> def is_obstructed( +> self, +> / +> ) + +Returns whether there is an obstruction. + +:rtype: bool + + +##### Method `is_valid` {#anise.astro.AzElRange.is_valid} + +> def is_valid( +> self, +> / +> ) + +Returns false if the range is less than one millimeter, or any of the angles are NaN. + +:rtype: bool + + +### Class `Ellipsoid` {#anise.astro.Ellipsoid} + +> class Ellipsoid( +> semi_major_equatorial_radius_km, +> polar_radius_km=None, +> semi_minor_equatorial_radius_km=None +> ) + +Only the tri-axial Ellipsoid shape model is currently supported by ANISE. +This is directly inspired from SPICE PCK. +> For each body, three radii are listed: The first number is +> the largest equatorial radius (the length of the semi-axis +> containing the prime meridian), the second number is the smaller +> equatorial radius, and the third is the polar radius. + +Example: Radii of the Earth. + + BODY399_RADII = ( 6378.1366 6378.1366 6356.7519 ) + +:type semi_major_equatorial_radius_km: float +:type polar_radius_km: float, optional +:type semi_minor_equatorial_radius_km: float, optional +:rtype: Ellipsoid + + +#### Instance variables + + +##### Variable `polar_radius_km` {#anise.astro.Ellipsoid.polar_radius_km} + +:rtype: float + + +##### Variable `semi_major_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_major_equatorial_radius_km} + +:rtype: float + + +##### Variable `semi_minor_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_minor_equatorial_radius_km} + +:rtype: float + + +#### Methods + + +##### Method `flattening` {#anise.astro.Ellipsoid.flattening} + +> def flattening( +> self, +> / +> ) + +Returns the flattening ratio, computed from the mean equatorial radius and the polar radius + +:rtype: float + + +##### Method `is_sphere` {#anise.astro.Ellipsoid.is_sphere} + +> def is_sphere( +> self, +> / +> ) + +Returns true if the polar radius is equal to the semi minor radius. + +:rtype: bool + + +##### Method `is_spheroid` {#anise.astro.Ellipsoid.is_spheroid} + +> def is_spheroid( +> self, +> / +> ) + +Returns true if the semi major and minor radii are equal + +:rtype: bool + + +##### Method `mean_equatorial_radius_km` {#anise.astro.Ellipsoid.mean_equatorial_radius_km} + +> def mean_equatorial_radius_km( +> self, +> / +> ) + +Returns the mean equatorial radius in kilometers + +:rtype: float + + +### Class `Frame` {#anise.astro.Frame} + +> class Frame( +> ephemeris_id, +> orientation_id, +> mu_km3_s2=None, +> shape=None +> ) + +A Frame uniquely defined by its ephemeris center and orientation. Refer to FrameDetail for frames combined with parameters. + +:type ephemeris_id: int +:type orientation_id: int +:type mu_km3_s2: float, optional +:type shape: Ellipsoid, optional +:rtype: Frame + + +#### Instance variables + + +##### Variable `ephemeris_id` {#anise.astro.Frame.ephemeris_id} + +:rtype: int + + +##### Variable `orientation_id` {#anise.astro.Frame.orientation_id} + +:rtype: int + + +##### Variable `shape` {#anise.astro.Frame.shape} + +:rtype: Ellipsoid + + +#### Methods + + +##### Method `ephem_origin_id_match` {#anise.astro.Frame.ephem_origin_id_match} + +> def ephem_origin_id_match( +> self, +> /, +> other_id +> ) + +Returns true if the ephemeris origin is equal to the provided ID + +:type other_id: int +:rtype: bool + + +##### Method `ephem_origin_match` {#anise.astro.Frame.ephem_origin_match} + +> def ephem_origin_match( +> self, +> /, +> other +> ) + +Returns true if the ephemeris origin is equal to the provided frame + +:type other: Frame +:rtype: bool + + +##### Method `flattening` {#anise.astro.Frame.flattening} + +> def flattening( +> self, +> / +> ) + +Returns the flattening ratio (unitless) + +:rtype: float + + +##### Method `is_celestial` {#anise.astro.Frame.is_celestial} + +> def is_celestial( +> self, +> / +> ) + +Returns whether this is a celestial frame + +:rtype: bool + + +##### Method `is_geodetic` {#anise.astro.Frame.is_geodetic} + +> def is_geodetic( +> self, +> / +> ) + +Returns whether this is a geodetic frame + +:rtype: bool + + +##### Method `mean_equatorial_radius_km` {#anise.astro.Frame.mean_equatorial_radius_km} + +> def mean_equatorial_radius_km( +> self, +> / +> ) + +Returns the mean equatorial radius in km, if defined + +:rtype: float + + +##### Method `mu_km3_s2` {#anise.astro.Frame.mu_km3_s2} + +> def mu_km3_s2( +> self, +> / +> ) + +Returns the gravitational parameters of this frame, if defined + +:rtype: float + + +##### Method `orient_origin_id_match` {#anise.astro.Frame.orient_origin_id_match} + +> def orient_origin_id_match( +> self, +> /, +> other_id +> ) + +Returns true if the orientation origin is equal to the provided ID + +:type other_id: int +:rtype: bool + + +##### Method `orient_origin_match` {#anise.astro.Frame.orient_origin_match} + +> def orient_origin_match( +> self, +> /, +> other +> ) + +Returns true if the orientation origin is equal to the provided frame + +:type other: Frame +:rtype: bool + + +##### Method `polar_radius_km` {#anise.astro.Frame.polar_radius_km} + +> def polar_radius_km( +> self, +> / +> ) + +Returns the polar radius in km, if defined + +:rtype: float + + +##### Method `semi_major_radius_km` {#anise.astro.Frame.semi_major_radius_km} + +> def semi_major_radius_km( +> self, +> / +> ) + +Returns the semi major radius of the tri-axial ellipoid shape of this frame, if defined + +:rtype: float + + +##### Method `strip` {#anise.astro.Frame.strip} + +> def strip( +> self, +> / +> ) + +Removes the graviational parameter and the shape information from this frame. +Use this to prevent astrodynamical computations. + +:rtype: None + + +##### Method `with_ephem` {#anise.astro.Frame.with_ephem} + +> def with_ephem( +> self, +> /, +> new_ephem_id +> ) + +Returns a copy of this Frame whose ephemeris ID is set to the provided ID + +:type new_ephem_id: int +:rtype: Frame + + +##### Method `with_mu_km3_s2` {#anise.astro.Frame.with_mu_km3_s2} + +> def with_mu_km3_s2( +> self, +> /, +> mu_km3_s2 +> ) + +Returns a copy of this frame with the graviational parameter set to the new value. + +:type mu_km3_s2: float +:rtype: Frame + + +##### Method `with_orient` {#anise.astro.Frame.with_orient} + +> def with_orient( +> self, +> /, +> new_orient_id +> ) + +Returns a copy of this Frame whose orientation ID is set to the provided ID + +:type new_orient_id: int +:rtype: Frame + + +### Class `Occultation` {#anise.astro.Occultation} + +> class Occultation( +> ... +> ) + +Stores the result of an occultation computation with the occulation percentage +Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details. + + +#### Instance variables + + +##### Variable `back_frame` {#anise.astro.Occultation.back_frame} + +:rtype: Frame + + +##### Variable `epoch` {#anise.astro.Occultation.epoch} + +:rtype: Epoch + + +##### Variable `front_frame` {#anise.astro.Occultation.front_frame} + +:rtype: Frame + + +##### Variable `percentage` {#anise.astro.Occultation.percentage} + +:rtype: float + + +#### Methods + + +##### Method `factor` {#anise.astro.Occultation.factor} + +> def factor( +> self, +> / +> ) + +Returns the percentage as a factor between 0 and 1 + +:rtype: float + + +##### Method `is_eclipse_computation` {#anise.astro.Occultation.is_eclipse_computation} + +> def is_eclipse_computation( +> self, +> / +> ) + +Returns true if the back object is the Sun, false otherwise + +:rtype: bool + + +##### Method `is_obstructed` {#anise.astro.Occultation.is_obstructed} + +> def is_obstructed( +> self, +> / +> ) + +Returns true if the occultation percentage is greater than or equal 99.999% + +:rtype: bool + + +##### Method `is_partial` {#anise.astro.Occultation.is_partial} + +> def is_partial( +> self, +> / +> ) + +Returns true if neither occulted nor visible (i.e. penumbra for solar eclipsing) + +:rtype: bool + + +##### Method `is_visible` {#anise.astro.Occultation.is_visible} + +> def is_visible( +> self, +> / +> ) + +Returns true if the occultation percentage is less than or equal 0.001% + +:rtype: bool + + +### Class `Orbit` {#anise.astro.Orbit} + +> class Orbit( +> x_km, +> y_km, +> z_km, +> vx_km_s, +> vy_km_s, +> vz_km_s, +> epoch, +> frame +> ) + +Defines a Cartesian state in a given frame at a given epoch in a given time scale. Radius data is expressed in kilometers. Velocity data is expressed in kilometers per second. +Regardless of the constructor used, this struct stores all the state information in Cartesian coordinates as these are always non singular. + +Unless noted otherwise, algorithms are from GMAT 2016a [StateConversionUtil.cpp](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/util/StateConversionUtil.cpp). + +:type x_km: float +:type y_km: float +:type z_km: float +:type vx_km_s: float +:type vy_km_s: float +:type vz_km_s: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +#### Instance variables + + +##### Variable `epoch` {#anise.astro.Orbit.epoch} + +:rtype: Epoch + + +##### Variable `frame` {#anise.astro.Orbit.frame} + +:rtype: Frame + + +##### Variable `vx_km_s` {#anise.astro.Orbit.vx_km_s} + +:rtype: float + + +##### Variable `vy_km_s` {#anise.astro.Orbit.vy_km_s} + +:rtype: float + + +##### Variable `vz_km` {#anise.astro.Orbit.vz_km} + +:type vz_km_s: float +:rtype: None + + +##### Variable `vz_km_s` {#anise.astro.Orbit.vz_km_s} + +:rtype: float + + +##### Variable `x_km` {#anise.astro.Orbit.x_km} + +:rtype: float + + +##### Variable `y_km` {#anise.astro.Orbit.y_km} + +:rtype: float + + +##### Variable `z_km` {#anise.astro.Orbit.z_km} + +:rtype: float + + +#### Methods + + +##### Method `abs_difference` {#anise.astro.Orbit.abs_difference} + +> def abs_difference( +> self, +> /, +> other +> ) + +Returns the absolute position and velocity differences in km and km/s between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: typing.Tuple + + +##### Method `abs_pos_diff_km` {#anise.astro.Orbit.abs_pos_diff_km} + +> def abs_pos_diff_km( +> self, +> /, +> other +> ) + +Returns the absolute position difference in kilometer between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `abs_vel_diff_km_s` {#anise.astro.Orbit.abs_vel_diff_km_s} + +> def abs_vel_diff_km_s( +> self, +> /, +> other +> ) + +Returns the absolute velocity difference in kilometer per second between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `add_aop_deg` {#anise.astro.Orbit.add_aop_deg} + +> def add_aop_deg( +> self, +> /, +> delta_aop_deg +> ) + +Returns a copy of the state with a provided AOP added to the current one + +:type delta_aop_deg: float +:rtype: Orbit + + +##### Method `add_apoapsis_periapsis_km` {#anise.astro.Orbit.add_apoapsis_periapsis_km} + +> def add_apoapsis_periapsis_km( +> self, +> /, +> delta_ra_km, +> delta_rp_km +> ) + +Returns a copy of this state with the provided apoasis and periapsis added to the current values + +:type delta_ra_km: float +:type delta_rp_km: float +:rtype: Orbit + + +##### Method `add_ecc` {#anise.astro.Orbit.add_ecc} + +> def add_ecc( +> self, +> /, +> delta_ecc +> ) + +Returns a copy of the state with a provided ECC added to the current one + +:type delta_ecc: float +:rtype: Orbit + + +##### Method `add_inc_deg` {#anise.astro.Orbit.add_inc_deg} + +> def add_inc_deg( +> self, +> /, +> delta_inc_deg +> ) + +Returns a copy of the state with a provided INC added to the current one + +:type delta_inc_deg: float +:rtype: None + + +##### Method `add_raan_deg` {#anise.astro.Orbit.add_raan_deg} + +> def add_raan_deg( +> self, +> /, +> delta_raan_deg +> ) + +Returns a copy of the state with a provided RAAN added to the current one + +:type delta_raan_deg: float +:rtype: Orbit + + +##### Method `add_sma_km` {#anise.astro.Orbit.add_sma_km} + +> def add_sma_km( +> self, +> /, +> delta_sma_km +> ) + +Returns a copy of the state with a provided SMA added to the current one + +:type delta_sma_km: float +:rtype: Orbit + + +##### Method `add_ta_deg` {#anise.astro.Orbit.add_ta_deg} + +> def add_ta_deg( +> self, +> /, +> delta_ta_deg +> ) + +Returns a copy of the state with a provided TA added to the current one + +:type delta_ta_deg: float +:rtype: Orbit + + +##### Method `altitude_km` {#anise.astro.Orbit.altitude_km} + +> def altitude_km( +> self, +> / +> ) + +Returns the altitude in km + +:rtype: float + + +##### Method `aol_deg` {#anise.astro.Orbit.aol_deg} + +> def aol_deg( +> self, +> / +> ) + +Returns the argument of latitude in degrees + +NOTE: If the orbit is near circular, the AoL will be computed from the true longitude +instead of relying on the ill-defined true anomaly. + +:rtype: float + + +##### Method `aop_deg` {#anise.astro.Orbit.aop_deg} + +> def aop_deg( +> self, +> / +> ) + +Returns the argument of periapsis in degrees + +:rtype: float + + +##### Method `apoapsis_altitude_km` {#anise.astro.Orbit.apoapsis_altitude_km} + +> def apoapsis_altitude_km( +> self, +> / +> ) + +Returns the altitude of apoapsis (or apogee around Earth), in kilometers. + +:rtype: float + + +##### Method `apoapsis_km` {#anise.astro.Orbit.apoapsis_km} + +> def apoapsis_km( +> self, +> / +> ) + +Returns the radius of apoapsis (or apogee around Earth), in kilometers. + +:rtype: float + + +##### Method `at_epoch` {#anise.astro.Orbit.at_epoch} + +> def at_epoch( +> self, +> /, +> new_epoch +> ) + +Adjusts the true anomaly of this orbit using the mean anomaly. + +##### Astrodynamics note +This is not a true propagation of the orbit. This is akin to a two body propagation ONLY without any other force models applied. +Use Nyx for high fidelity propagation. + +:type new_epoch: Epoch +:rtype: Orbit + + +##### Method `c3_km2_s2` {#anise.astro.Orbit.c3_km2_s2} + +> def c3_km2_s2( +> self, +> / +> ) + +Returns the $C_3$ of this orbit in km^2/s^2 + +:rtype: float + + +##### Method `cartesian_pos_vel` {#anise.astro.Orbit.cartesian_pos_vel} + +> def cartesian_pos_vel( +> self, +> / +> ) + +Returns this state as a Cartesian vector of size 6 in [km, km, km, km/s, km/s, km/s] + +Note that the time is **not** returned in the vector. +:rtype: numpy.array + + +##### Method `dcm3x3_from_rcn_to_inertial` {#anise.astro.Orbit.dcm3x3_from_rcn_to_inertial} + +> def dcm3x3_from_rcn_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{r}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure + +:rtype: DCM + + +##### Method `dcm3x3_from_ric_to_inertial` {#anise.astro.Orbit.dcm3x3_from_ric_to_inertial} + +> def dcm3x3_from_ric_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame + +##### Frame warning +If the state is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Build the c vector as the normalized orbital momentum vector +2. Build the i vector as the cross product of \hat{r} and c +3. Build the RIC DCM as a 3x3 of the columns [\hat{r}, \hat{i}, \hat{c}] +4. Return the DCM structure **without** accounting for the transport theorem. + +:rtype: DCM + + +##### Method `dcm3x3_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm3x3_from_topocentric_to_body_fixed} + +> def dcm3x3_from_topocentric_to_body_fixed( +> self, +> / +> ) + +Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state. + +##### Frame warning +If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID. + +##### Source +From the GMAT MathSpec, page 30 section 2.6.9 and from Calculate\_RFT in TopocentricAxes.cpp, this returns the +rotation matrix from the topocentric frame (SEZ) to body fixed frame. +In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric +to body fixed. + +:rtype: DCM + + +##### Method `dcm3x3_from_vnc_to_inertial` {#anise.astro.Orbit.dcm3x3_from_vnc_to_inertial} + +> def dcm3x3_from_vnc_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{v}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure. + +:rtype: DCM + + +##### Method `dcm_from_rcn_to_inertial` {#anise.astro.Orbit.dcm_from_rcn_to_inertial} + +> def dcm_from_rcn_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{r}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `dcm_from_ric_to_inertial` {#anise.astro.Orbit.dcm_from_ric_to_inertial} + +> def dcm_from_ric_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame + +##### Frame warning +If the state is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute the state data one millisecond before and one millisecond assuming two body dynamics +2. Compute the DCM for this state, and the pre and post states +3. Build the c vector as the normalized orbital momentum vector +4. Build the i vector as the cross product of \hat{r} and c +5. Build the RIC DCM as a 3x3 of the columns [\hat{r}, \hat{i}, \hat{c}], for the post, post, and current states +6. Compute the difference between the DCMs of the pre and post states, to build the DCM time derivative +7. Return the DCM structure with a 6x6 state DCM. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `dcm_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm_from_topocentric_to_body_fixed} + +> def dcm_from_topocentric_to_body_fixed( +> self, +> /, +> _from +> ) + +Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state. + +##### Frame warnings ++ If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID. ++ (Usually) no time derivative can be computed: the orbit is expected to be a body fixed frame where the at\_epoch function will fail. Exceptions for Moon body fixed frames. + +##### UNUSED Arguments ++ from: ID of this new frame. Only used to set the "from" frame of the DCM. -- No longer used since 0.5.3 + +##### Source +From the GMAT MathSpec, page 30 section 2.6.9 and from Calculate\_RFT in TopocentricAxes.cpp, this returns the +rotation matrix from the topocentric frame (SEZ) to body fixed frame. +In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric +to body fixed. + +:type _from: float +:rtype: DCM + + +##### Method `dcm_from_vnc_to_inertial` {#anise.astro.Orbit.dcm_from_vnc_to_inertial} + +> def dcm_from_vnc_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{v}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Compute the difference between the DCMs of the pre and post states (+/- 1 ms), to build the DCM time derivative +4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `declination_deg` {#anise.astro.Orbit.declination_deg} + +> def declination_deg( +> self, +> / +> ) + +Returns the declination of this orbit in degrees + +:rtype: float + + +##### Method `distance_to_km` {#anise.astro.Orbit.distance_to_km} + +> def distance_to_km( +> self, +> /, +> other +> ) + +Returns the distance in kilometers between this state and another state, if both frame match (epoch does not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `duration_to_radius` {#anise.astro.Orbit.duration_to_radius} + +> def duration_to_radius( +> self, +> /, +> radius_km +> ) + +Calculates the duration to reach a specific radius in the orbit. + +This function computes the time it will take for the orbiting body to reach +the given radius\_km from its current position. The calculation assumes +two-body dynamics and considers the direction of motion. + +##### Assumptions & Limitations + +- Assumes pure Keplerian motion. +- For elliptical orbits, if the radius is reachable at two points (ascending and descending parts + of the orbit), this function calculates the time to reach the radius corresponding to the + true anomaly in \[0, PI] (typically the ascending part or up to apoapsis if starting past periapsis). +- For circular orbits, if the radius is within the apoapse and periapse, then a duration of zero is returned. +- For hyperbolic/parabolic orbits, the true anomaly at radius is also computed in \[0, PI]. If this + point is in the past, the function returns an error, as it doesn't look for solutions on the + departing leg if `nu > PI` would be required (unless current TA is already > PI and target radius is further along). + The current implementation strictly uses the acos result, so nu\_rad\_at\_radius is always `0 <= nu <= PI`. + This means it finds the time to reach the radius on the path from periapsis up to the point where true anomaly is PI. + +:type radius_km: float +:rtype: Duration + + +##### Method `ea_deg` {#anise.astro.Orbit.ea_deg} + +> def ea_deg( +> self, +> / +> ) + +Returns the eccentric anomaly in degrees + +This is a conversion from GMAT's StateConversionUtil::TrueToEccentricAnomaly + +:rtype: float + + +##### Method `ecc` {#anise.astro.Orbit.ecc} + +> def ecc( +> self, +> / +> ) + +Returns the eccentricity (no unit) + +:rtype: float + + +##### Method `energy_km2_s2` {#anise.astro.Orbit.energy_km2_s2} + +> def energy_km2_s2( +> self, +> / +> ) + +Returns the specific mechanical energy in km^2/s^2 + +:rtype: float + + +##### Method `eq_within` {#anise.astro.Orbit.eq_within} + +> def eq_within( +> self, +> /, +> other, +> radial_tol_km, +> velocity_tol_km_s +> ) + +Returns whether this orbit and another are equal within the specified radial and velocity absolute tolerances + +:type other: Orbit +:type radial_tol_km: float +:type velocity_tol_km_s: float +:rtype: bool + + +##### Method `fpa_deg` {#anise.astro.Orbit.fpa_deg} + +> def fpa_deg( +> self, +> / +> ) + +Returns the flight path angle in degrees + +:rtype: float + + +##### Method `from_cartesian` {#anise.astro.Orbit.from_cartesian} + +> def from_cartesian( +> x_km, +> y_km, +> z_km, +> vx_km_s, +> vy_km_s, +> vz_km_s, +> epoch, +> frame +> ) + +Creates a new Cartesian state in the provided frame at the provided Epoch. + +**Units:** km, km, km, km/s, km/s, km/s + +:type x_km: float +:type y_km: float +:type z_km: float +:type vx_km_s: float +:type vy_km_s: float +:type vz_km_s: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian` {#anise.astro.Orbit.from_keplerian} + +> def from_keplerian( +> sma_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit around the provided Celestial or Geoid frame from the Keplerian orbital elements. + +**Units:** km, none, degrees, degrees, degrees, degrees + +NOTE: The state is defined in Cartesian coordinates as they are non-singular. This causes rounding +errors when creating a state from its Keplerian orbital elements (cf. the state tests). +One should expect these errors to be on the order of 1e-12. + +:type sma_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_altitude` {#anise.astro.Orbit.from_keplerian_altitude} + +> def from_keplerian_altitude( +> sma_altitude_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit from the provided semi-major axis altitude in kilometers + +:type sma_altitude_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_apsis_altitude` {#anise.astro.Orbit.from_keplerian_apsis_altitude} + +> def from_keplerian_apsis_altitude( +> apo_alt_km, +> peri_alt_km, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit from the provided altitudes of apoapsis and periapsis, in kilometers + +:type apo_alt_km: float +:type peri_alt_km: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_apsis_radii` {#anise.astro.Orbit.from_keplerian_apsis_radii} + +> def from_keplerian_apsis_radii( +> r_a_km, +> r_p_km, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Attempts to create a new Orbit from the provided radii of apoapsis and periapsis, in kilometers + +:type r_a_km: float +:type r_p_km: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_mean_anomaly` {#anise.astro.Orbit.from_keplerian_mean_anomaly} + +> def from_keplerian_mean_anomaly( +> sma_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ma_deg, +> epoch, +> frame +> ) + +Initializes a new orbit from the Keplerian orbital elements using the mean anomaly instead of the true anomaly. + +##### Implementation notes +This function starts by converting the mean anomaly to true anomaly, and then it initializes the orbit +using the keplerian(..) method. +The conversion is from GMAT's MeanToTrueAnomaly function, transliterated originally by Claude and GPT4 with human adjustments. + +:type sma_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ma_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_latlongalt` {#anise.astro.Orbit.from_latlongalt} + +> def from_latlongalt( +> latitude_deg, +> longitude_deg, +> height_km, +> angular_velocity, +> epoch, +> frame +> ) + +Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid given the angular velocity. + +**Units:** degrees, degrees, km, rad/s +NOTE: This computation differs from the spherical coordinates because we consider the flattening of body. +Reference: G. Xu and Y. Xu, "GPS", DOI 10.1007/978-3-662-50367-6_2, 2016 + +:type latitude_deg: float +:type longitude_deg: float +:type height_km: float +:type angular_velocity: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `height_km` {#anise.astro.Orbit.height_km} + +> def height_km( +> self, +> / +> ) + +Returns the geodetic height in km. + +Reference: Vallado, 4th Ed., Algorithm 12 page 172. + +:rtype: float + + +##### Method `hmag` {#anise.astro.Orbit.hmag} + +> def hmag( +> self, +> / +> ) + +Returns the norm of the orbital momentum + +:rtype: float + + +##### Method `hx` {#anise.astro.Orbit.hx} + +> def hx( +> self, +> / +> ) + +Returns the orbital momentum value on the X axis + +:rtype: float + + +##### Method `hy` {#anise.astro.Orbit.hy} + +> def hy( +> self, +> / +> ) + +Returns the orbital momentum value on the Y axis + +:rtype: float + + +##### Method `hyperbolic_anomaly_deg` {#anise.astro.Orbit.hyperbolic_anomaly_deg} + +> def hyperbolic_anomaly_deg( +> self, +> / +> ) + +Returns the hyperbolic anomaly in degrees between 0 and 360.0 +Returns an error if the orbit is not hyperbolic. + +:rtype: float + + +##### Method `hz` {#anise.astro.Orbit.hz} + +> def hz( +> self, +> / +> ) + +Returns the orbital momentum value on the Z axis + +:rtype: float + + +##### Method `inc_deg` {#anise.astro.Orbit.inc_deg} + +> def inc_deg( +> self, +> / +> ) + +Returns the inclination in degrees + +:rtype: float + + +##### Method `is_brouwer_short_valid` {#anise.astro.Orbit.is_brouwer_short_valid} + +> def is_brouwer_short_valid( +> self, +> / +> ) + +Returns whether this state satisfies the requirement to compute the Mean Brouwer Short orbital +element set. + +This is a conversion from GMAT's StateConversionUtil::CartesianToBrouwerMeanShort. +The details are at the log level info. +NOTE: Mean Brouwer Short are only defined around Earth. However, nyx does *not* check the +main celestial body around which the state is defined (GMAT does perform this verification). + +:rtype: bool + + +##### Method `latitude_deg` {#anise.astro.Orbit.latitude_deg} + +> def latitude_deg( +> self, +> / +> ) + +Returns the geodetic latitude (φ) in degrees. Value is between -180 and +180 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `latlongalt` {#anise.astro.Orbit.latlongalt} + +> def latlongalt( +> self, +> / +> ) + +Returns the geodetic latitude, geodetic longitude, and geodetic height, respectively in degrees, degrees, and kilometers. + +##### Algorithm +This uses the Heikkinen procedure, which is not iterative. The results match Vallado and GMAT. + +:rtype: typing.Tuple + + +##### Method `light_time` {#anise.astro.Orbit.light_time} + +> def light_time( +> self, +> / +> ) + +Returns the light time duration between this object and the origin of its reference frame. + +:rtype: Duration + + +##### Method `longitude_360_deg` {#anise.astro.Orbit.longitude_360_deg} + +> def longitude_360_deg( +> self, +> / +> ) + +Returns the geodetic longitude (λ) in degrees. Value is between 0 and 360 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `longitude_deg` {#anise.astro.Orbit.longitude_deg} + +> def longitude_deg( +> self, +> / +> ) + +Returns the geodetic longitude (λ) in degrees. Value is between -180 and 180 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `ltan_deg` {#anise.astro.Orbit.ltan_deg} + +> def ltan_deg( +> self, +> / +> ) + +Returns the Longitude of the Ascending Node (LTAN), or an error of equatorial orbits + +:rtype: float + + +##### Method `ma_deg` {#anise.astro.Orbit.ma_deg} + +> def ma_deg( +> self, +> / +> ) + +Returns the mean anomaly in degrees + +This is a conversion from GMAT's StateConversionUtil::TrueToMeanAnomaly + +:rtype: float + + +##### Method `mean_motion_deg_s` {#anise.astro.Orbit.mean_motion_deg_s} + +> def mean_motion_deg_s( +> self, +> / +> ) + +Returns the mean motion in degrees per seconds + +:rtype: float + + +##### Method `periapsis_altitude_km` {#anise.astro.Orbit.periapsis_altitude_km} + +> def periapsis_altitude_km( +> self, +> / +> ) + +Returns the altitude of periapsis (or perigee around Earth), in kilometers. + +:rtype: float + + +##### Method `periapsis_km` {#anise.astro.Orbit.periapsis_km} + +> def periapsis_km( +> self, +> / +> ) + +Returns the radius of periapsis (or perigee around Earth), in kilometers. + +:rtype: float + + +##### Method `period` {#anise.astro.Orbit.period} + +> def period( +> self, +> / +> ) + +Returns the period in seconds + +:rtype: Duration + + +##### Method `raan_deg` {#anise.astro.Orbit.raan_deg} + +> def raan_deg( +> self, +> / +> ) + +Returns the right ascension of the ascending node in degrees + +:rtype: float + + +##### Method `rel_difference` {#anise.astro.Orbit.rel_difference} + +> def rel_difference( +> self, +> /, +> other +> ) + +Returns the relative difference between this orbit and another for the position and velocity, respectively the first and second return values. +Both return values are UNITLESS because the relative difference is computed as the absolute difference divided by the rmag and vmag of this object. +Raises an error if the frames do not match, if the position is zero or the velocity is zero. + +:type other: Orbit +:rtype: typing.Tuple + + +##### Method `rel_pos_diff` {#anise.astro.Orbit.rel_pos_diff} + +> def rel_pos_diff( +> self, +> /, +> other +> ) + +Returns the relative position difference (unitless) between this orbit and another. +This is computed by dividing the absolute difference by the norm of this object's radius vector. +If the radius is zero, this function raises a math error. +Raises an error if the frames do not match or (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `rel_vel_diff` {#anise.astro.Orbit.rel_vel_diff} + +> def rel_vel_diff( +> self, +> /, +> other +> ) + +Returns the absolute velocity difference in kilometer per second between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `ric_difference` {#anise.astro.Orbit.ric_difference} + +> def ric_difference( +> self, +> /, +> other +> ) + +Returns a Cartesian state representing the RIC difference between self and other, in position and velocity (with transport theorem). +Refer to dcm_from_ric_to_inertial for details on the RIC frame. + +##### Algorithm +1. Compute the RIC DCM of self +2. Rotate self into the RIC frame +3. Rotation other into the RIC frame +4. Compute the difference between these two states +5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState + +:type other: Orbit +:rtype: Orbit + + +##### Method `right_ascension_deg` {#anise.astro.Orbit.right_ascension_deg} + +> def right_ascension_deg( +> self, +> / +> ) + +Returns the right ascension of this orbit in degrees + +:rtype: float + + +##### Method `rmag_km` {#anise.astro.Orbit.rmag_km} + +> def rmag_km( +> self, +> / +> ) + +Returns the magnitude of the radius vector in km + +:rtype: float + + +##### Method `rms_radius_km` {#anise.astro.Orbit.rms_radius_km} + +> def rms_radius_km( +> self, +> /, +> other +> ) + +Returns the root sum squared (RMS) radius difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rms_velocity_km_s` {#anise.astro.Orbit.rms_velocity_km_s} + +> def rms_velocity_km_s( +> self, +> /, +> other +> ) + +Returns the root sum squared (RMS) velocity difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rss_radius_km` {#anise.astro.Orbit.rss_radius_km} + +> def rss_radius_km( +> self, +> /, +> other +> ) + +Returns the root mean squared (RSS) radius difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rss_velocity_km_s` {#anise.astro.Orbit.rss_velocity_km_s} + +> def rss_velocity_km_s( +> self, +> /, +> other +> ) + +Returns the root mean squared (RSS) velocity difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `semi_minor_axis_km` {#anise.astro.Orbit.semi_minor_axis_km} + +> def semi_minor_axis_km( +> self, +> / +> ) + +Returns the semi minor axis in km, includes code for a hyperbolic orbit + +:rtype: float + + +##### Method `semi_parameter_km` {#anise.astro.Orbit.semi_parameter_km} + +> def semi_parameter_km( +> self, +> / +> ) + +Returns the semi parameter (or semilatus rectum) + +:rtype: float + + +##### Method `set_aop_deg` {#anise.astro.Orbit.set_aop_deg} + +> def set_aop_deg( +> self, +> /, +> new_aop_deg +> ) + +Mutates this orbit to change the AOP + +:type new_aop_deg: float +:rtype: None + + +##### Method `set_ecc` {#anise.astro.Orbit.set_ecc} + +> def set_ecc( +> self, +> /, +> new_ecc +> ) + +Mutates this orbit to change the ECC + +:type new_ecc: float +:rtype: None + + +##### Method `set_inc_deg` {#anise.astro.Orbit.set_inc_deg} + +> def set_inc_deg( +> self, +> /, +> new_inc_deg +> ) + +Mutates this orbit to change the INC + +:type new_inc_deg: float +:rtype: None + + +##### Method `set_raan_deg` {#anise.astro.Orbit.set_raan_deg} + +> def set_raan_deg( +> self, +> /, +> new_raan_deg +> ) + +Mutates this orbit to change the RAAN + +:type new_raan_deg: float +:rtype: None + + +##### Method `set_sma_km` {#anise.astro.Orbit.set_sma_km} + +> def set_sma_km( +> self, +> /, +> new_sma_km +> ) + +Mutates this orbit to change the SMA + +:type new_sma_km: float +:rtype: None + + +##### Method `set_ta_deg` {#anise.astro.Orbit.set_ta_deg} + +> def set_ta_deg( +> self, +> /, +> new_ta_deg +> ) + +Mutates this orbit to change the TA + +:type new_ta_deg: float +:rtype: None + + +##### Method `sma_altitude_km` {#anise.astro.Orbit.sma_altitude_km} + +> def sma_altitude_km( +> self, +> / +> ) + +Returns the SMA altitude in km + +:rtype: float + + +##### Method `sma_km` {#anise.astro.Orbit.sma_km} + +> def sma_km( +> self, +> / +> ) + +Returns the semi-major axis in km + +:rtype: float + + +##### Method `ta_deg` {#anise.astro.Orbit.ta_deg} + +> def ta_deg( +> self, +> / +> ) + +Returns the true anomaly in degrees between 0 and 360.0 + +NOTE: This function will emit a warning stating that the TA should be avoided if in a very near circular orbit +Code from + +LIMITATION: For an orbit whose true anomaly is (very nearly) 0.0 or 180.0, this function may return either 0.0 or 180.0 with a very small time increment. +This is due to the precision of the cosine calculation: if the arccosine calculation is out of bounds, the sign of the cosine of the true anomaly is used +to determine whether the true anomaly should be 0.0 or 180.0. **In other words**, there is an ambiguity in the computation in the true anomaly exactly at 180.0 and 0.0. + +:rtype: float + + +##### Method `ta_dot_deg_s` {#anise.astro.Orbit.ta_dot_deg_s} + +> def ta_dot_deg_s( +> self, +> / +> ) + +Returns the time derivative of the true anomaly computed as the 360.0 degrees divided by the orbital period (in seconds). + +:rtype: float + + +##### Method `tlong_deg` {#anise.astro.Orbit.tlong_deg} + +> def tlong_deg( +> self, +> / +> ) + +Returns the true longitude in degrees + +:rtype: float + + +##### Method `velocity_declination_deg` {#anise.astro.Orbit.velocity_declination_deg} + +> def velocity_declination_deg( +> self, +> / +> ) + +Returns the velocity declination of this orbit in degrees + +:rtype: float + + +##### Method `vinf_periapsis_km` {#anise.astro.Orbit.vinf_periapsis_km} + +> def vinf_periapsis_km( +> self, +> /, +> turn_angle_degrees +> ) + +Returns the radius of periapse in kilometers for the provided turn angle of this hyperbolic orbit. +Returns an error if the orbit is not hyperbolic. + +:type turn_angle_degrees: float +:rtype: float + + +##### Method `vinf_turn_angle_deg` {#anise.astro.Orbit.vinf_turn_angle_deg} + +> def vinf_turn_angle_deg( +> self, +> /, +> periapsis_km +> ) + +Returns the turn angle in degrees for the provided radius of periapse passage of this hyperbolic orbit +Returns an error if the orbit is not hyperbolic. + +:type periapsis_km: float +:rtype: float + + +##### Method `vmag_km_s` {#anise.astro.Orbit.vmag_km_s} + +> def vmag_km_s( +> self, +> / +> ) + +Returns the magnitude of the velocity vector in km/s + +:rtype: float + + +##### Method `vnc_difference` {#anise.astro.Orbit.vnc_difference} + +> def vnc_difference( +> self, +> /, +> other +> ) + +Returns a Cartesian state representing the VNC difference between self and other, in position and velocity (with transport theorem). +Refer to dcm_from_vnc_to_inertial for details on the VNC frame. + +##### Algorithm +1. Compute the VNC DCM of self +2. Rotate self into the VNC frame +3. Rotation other into the VNC frame +4. Compute the difference between these two states +5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState + +:type other: Orbit +:rtype: Orbit + + +##### Method `with_aop_deg` {#anise.astro.Orbit.with_aop_deg} + +> def with_aop_deg( +> self, +> /, +> new_aop_deg +> ) + +Returns a copy of the state with a new AOP + +:type new_aop_deg: float +:rtype: Orbit + + +##### Method `with_apoapsis_periapsis_km` {#anise.astro.Orbit.with_apoapsis_periapsis_km} + +> def with_apoapsis_periapsis_km( +> self, +> /, +> new_ra_km, +> new_rp_km +> ) + +Returns a copy of this state with the provided apoasis and periapsis + +:type new_ra_km: float +:type new_rp_km: float +:rtype: Orbit + + +##### Method `with_ecc` {#anise.astro.Orbit.with_ecc} + +> def with_ecc( +> self, +> /, +> new_ecc +> ) + +Returns a copy of the state with a new ECC + +:type new_ecc: float +:rtype: Orbit + + +##### Method `with_inc_deg` {#anise.astro.Orbit.with_inc_deg} + +> def with_inc_deg( +> self, +> /, +> new_inc_deg +> ) + +Returns a copy of the state with a new INC + +:type new_inc_deg: float +:rtype: Orbit + + +##### Method `with_raan_deg` {#anise.astro.Orbit.with_raan_deg} + +> def with_raan_deg( +> self, +> /, +> new_raan_deg +> ) + +Returns a copy of the state with a new RAAN + +:type new_raan_deg: float +:rtype: Orbit + + +##### Method `with_sma_km` {#anise.astro.Orbit.with_sma_km} + +> def with_sma_km( +> self, +> /, +> new_sma_km +> ) + +Returns a copy of the state with a new SMA + +:type new_sma_km: float +:rtype: Orbit + + +##### Method `with_ta_deg` {#anise.astro.Orbit.with_ta_deg} + +> def with_ta_deg( +> self, +> /, +> new_ta_deg +> ) + +Returns a copy of the state with a new TA + +:type new_ta_deg: float +:rtype: Orbit + + +# Module `anise.astro.constants` {#anise.astro.constants} + + +## Classes + + +### Class `CelestialObjects` {#anise.astro.constants.CelestialObjects} + +> class CelestialObjects( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH` {#anise.astro.constants.CelestialObjects.EARTH} + + +##### Variable `EARTH_MOON_BARYCENTER` {#anise.astro.constants.CelestialObjects.EARTH_MOON_BARYCENTER} + + +##### Variable `JUPITER` {#anise.astro.constants.CelestialObjects.JUPITER} + + +##### Variable `JUPITER_BARYCENTER` {#anise.astro.constants.CelestialObjects.JUPITER_BARYCENTER} + + +##### Variable `MARS` {#anise.astro.constants.CelestialObjects.MARS} + + +##### Variable `MARS_BARYCENTER` {#anise.astro.constants.CelestialObjects.MARS_BARYCENTER} + + +##### Variable `MERCURY` {#anise.astro.constants.CelestialObjects.MERCURY} + + +##### Variable `MOON` {#anise.astro.constants.CelestialObjects.MOON} + + +##### Variable `NEPTUNE` {#anise.astro.constants.CelestialObjects.NEPTUNE} + + +##### Variable `NEPTUNE_BARYCENTER` {#anise.astro.constants.CelestialObjects.NEPTUNE_BARYCENTER} + + +##### Variable `PLUTO_BARYCENTER` {#anise.astro.constants.CelestialObjects.PLUTO_BARYCENTER} + + +##### Variable `SATURN` {#anise.astro.constants.CelestialObjects.SATURN} + + +##### Variable `SATURN_BARYCENTER` {#anise.astro.constants.CelestialObjects.SATURN_BARYCENTER} + + +##### Variable `SOLAR_SYSTEM_BARYCENTER` {#anise.astro.constants.CelestialObjects.SOLAR_SYSTEM_BARYCENTER} + + +##### Variable `SUN` {#anise.astro.constants.CelestialObjects.SUN} + + +##### Variable `URANUS` {#anise.astro.constants.CelestialObjects.URANUS} + + +##### Variable `URANUS_BARYCENTER` {#anise.astro.constants.CelestialObjects.URANUS_BARYCENTER} + + +##### Variable `VENUS` {#anise.astro.constants.CelestialObjects.VENUS} + + +### Class `Frames` {#anise.astro.constants.Frames} + +> class Frames( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH_ECLIPJ2000` {#anise.astro.constants.Frames.EARTH_ECLIPJ2000} + + +##### Variable `EARTH_ITRF93` {#anise.astro.constants.Frames.EARTH_ITRF93} + + +##### Variable `EARTH_J2000` {#anise.astro.constants.Frames.EARTH_J2000} + + +##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.astro.constants.Frames.EARTH_MOON_BARYCENTER_J2000} + + +##### Variable `EME2000` {#anise.astro.constants.Frames.EME2000} + + +##### Variable `IAU_EARTH_FRAME` {#anise.astro.constants.Frames.IAU_EARTH_FRAME} + + +##### Variable `IAU_JUPITER_FRAME` {#anise.astro.constants.Frames.IAU_JUPITER_FRAME} + + +##### Variable `IAU_MARS_FRAME` {#anise.astro.constants.Frames.IAU_MARS_FRAME} + + +##### Variable `IAU_MERCURY_FRAME` {#anise.astro.constants.Frames.IAU_MERCURY_FRAME} + + +##### Variable `IAU_MOON_FRAME` {#anise.astro.constants.Frames.IAU_MOON_FRAME} + + +##### Variable `IAU_NEPTUNE_FRAME` {#anise.astro.constants.Frames.IAU_NEPTUNE_FRAME} + + +##### Variable `IAU_SATURN_FRAME` {#anise.astro.constants.Frames.IAU_SATURN_FRAME} + + +##### Variable `IAU_URANUS_FRAME` {#anise.astro.constants.Frames.IAU_URANUS_FRAME} + + +##### Variable `IAU_VENUS_FRAME` {#anise.astro.constants.Frames.IAU_VENUS_FRAME} + + +##### Variable `JUPITER_BARYCENTER_J2000` {#anise.astro.constants.Frames.JUPITER_BARYCENTER_J2000} + + +##### Variable `MARS_BARYCENTER_J2000` {#anise.astro.constants.Frames.MARS_BARYCENTER_J2000} + + +##### Variable `MERCURY_J2000` {#anise.astro.constants.Frames.MERCURY_J2000} + + +##### Variable `MOON_J2000` {#anise.astro.constants.Frames.MOON_J2000} + + +##### Variable `MOON_ME_DE421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE421_FRAME} + + +##### Variable `MOON_ME_DE440_ME421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE440_ME421_FRAME} + + +##### Variable `MOON_ME_FRAME` {#anise.astro.constants.Frames.MOON_ME_FRAME} + + +##### Variable `MOON_PA_DE421_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE421_FRAME} + + +##### Variable `MOON_PA_DE440_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE440_FRAME} + + +##### Variable `MOON_PA_FRAME` {#anise.astro.constants.Frames.MOON_PA_FRAME} + + +##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.astro.constants.Frames.NEPTUNE_BARYCENTER_J2000} + + +##### Variable `PLUTO_BARYCENTER_J2000` {#anise.astro.constants.Frames.PLUTO_BARYCENTER_J2000} + + +##### Variable `SATURN_BARYCENTER_J2000` {#anise.astro.constants.Frames.SATURN_BARYCENTER_J2000} + + +##### Variable `SSB_J2000` {#anise.astro.constants.Frames.SSB_J2000} + + +##### Variable `SUN_J2000` {#anise.astro.constants.Frames.SUN_J2000} + + +##### Variable `URANUS_BARYCENTER_J2000` {#anise.astro.constants.Frames.URANUS_BARYCENTER_J2000} + + +##### Variable `VENUS_J2000` {#anise.astro.constants.Frames.VENUS_J2000} + + +### Class `Orientations` {#anise.astro.constants.Orientations} + +> class Orientations( +> ... +> ) + + +#### Class variables + + +##### Variable `ECLIPJ2000` {#anise.astro.constants.Orientations.ECLIPJ2000} + + +##### Variable `IAU_EARTH` {#anise.astro.constants.Orientations.IAU_EARTH} + + +##### Variable `IAU_JUPITER` {#anise.astro.constants.Orientations.IAU_JUPITER} + + +##### Variable `IAU_MARS` {#anise.astro.constants.Orientations.IAU_MARS} + + +##### Variable `IAU_MERCURY` {#anise.astro.constants.Orientations.IAU_MERCURY} + + +##### Variable `IAU_MOON` {#anise.astro.constants.Orientations.IAU_MOON} + + +##### Variable `IAU_NEPTUNE` {#anise.astro.constants.Orientations.IAU_NEPTUNE} + + +##### Variable `IAU_SATURN` {#anise.astro.constants.Orientations.IAU_SATURN} + + +##### Variable `IAU_URANUS` {#anise.astro.constants.Orientations.IAU_URANUS} + + +##### Variable `IAU_VENUS` {#anise.astro.constants.Orientations.IAU_VENUS} + + +##### Variable `ITRF93` {#anise.astro.constants.Orientations.ITRF93} + + +##### Variable `J2000` {#anise.astro.constants.Orientations.J2000} + + +##### Variable `MOON_ME` {#anise.astro.constants.Orientations.MOON_ME} + + +##### Variable `MOON_ME_DE421` {#anise.astro.constants.Orientations.MOON_ME_DE421} + + +##### Variable `MOON_ME_DE440_ME421` {#anise.astro.constants.Orientations.MOON_ME_DE440_ME421} + + +##### Variable `MOON_PA` {#anise.astro.constants.Orientations.MOON_PA} + + +##### Variable `MOON_PA_DE421` {#anise.astro.constants.Orientations.MOON_PA_DE421} + + +##### Variable `MOON_PA_DE440` {#anise.astro.constants.Orientations.MOON_PA_DE440} + + +### Class `UsualConstants` {#anise.astro.constants.UsualConstants} + +> class UsualConstants( +> ... +> ) + + +#### Class variables + + +##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_EARTH_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_MOON_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `SPEED_OF_LIGHT_KM_S` {#anise.astro.constants.UsualConstants.SPEED_OF_LIGHT_KM_S} + +----- +Generated by *pdoc* 0.11.6 (). diff --git a/docs/anise/reference/api/python/constants.md b/docs/anise/reference/api/python/constants.md new file mode 100644 index 0000000..67db056 --- /dev/null +++ b/docs/anise/reference/api/python/constants.md @@ -0,0 +1,257 @@ +# Module `anise.constants` {#anise.constants} + + +## Classes + + +### Class `CelestialObjects` {#anise.constants.CelestialObjects} + +> class CelestialObjects( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH` {#anise.constants.CelestialObjects.EARTH} + + +##### Variable `EARTH_MOON_BARYCENTER` {#anise.constants.CelestialObjects.EARTH_MOON_BARYCENTER} + + +##### Variable `JUPITER` {#anise.constants.CelestialObjects.JUPITER} + + +##### Variable `JUPITER_BARYCENTER` {#anise.constants.CelestialObjects.JUPITER_BARYCENTER} + + +##### Variable `MARS` {#anise.constants.CelestialObjects.MARS} + + +##### Variable `MARS_BARYCENTER` {#anise.constants.CelestialObjects.MARS_BARYCENTER} + + +##### Variable `MERCURY` {#anise.constants.CelestialObjects.MERCURY} + + +##### Variable `MOON` {#anise.constants.CelestialObjects.MOON} + + +##### Variable `NEPTUNE` {#anise.constants.CelestialObjects.NEPTUNE} + + +##### Variable `NEPTUNE_BARYCENTER` {#anise.constants.CelestialObjects.NEPTUNE_BARYCENTER} + + +##### Variable `PLUTO_BARYCENTER` {#anise.constants.CelestialObjects.PLUTO_BARYCENTER} + + +##### Variable `SATURN` {#anise.constants.CelestialObjects.SATURN} + + +##### Variable `SATURN_BARYCENTER` {#anise.constants.CelestialObjects.SATURN_BARYCENTER} + + +##### Variable `SOLAR_SYSTEM_BARYCENTER` {#anise.constants.CelestialObjects.SOLAR_SYSTEM_BARYCENTER} + + +##### Variable `SUN` {#anise.constants.CelestialObjects.SUN} + + +##### Variable `URANUS` {#anise.constants.CelestialObjects.URANUS} + + +##### Variable `URANUS_BARYCENTER` {#anise.constants.CelestialObjects.URANUS_BARYCENTER} + + +##### Variable `VENUS` {#anise.constants.CelestialObjects.VENUS} + + +### Class `Frames` {#anise.constants.Frames} + +> class Frames( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH_ECLIPJ2000` {#anise.constants.Frames.EARTH_ECLIPJ2000} + + +##### Variable `EARTH_ITRF93` {#anise.constants.Frames.EARTH_ITRF93} + + +##### Variable `EARTH_J2000` {#anise.constants.Frames.EARTH_J2000} + + +##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.constants.Frames.EARTH_MOON_BARYCENTER_J2000} + + +##### Variable `EME2000` {#anise.constants.Frames.EME2000} + + +##### Variable `IAU_EARTH_FRAME` {#anise.constants.Frames.IAU_EARTH_FRAME} + + +##### Variable `IAU_JUPITER_FRAME` {#anise.constants.Frames.IAU_JUPITER_FRAME} + + +##### Variable `IAU_MARS_FRAME` {#anise.constants.Frames.IAU_MARS_FRAME} + + +##### Variable `IAU_MERCURY_FRAME` {#anise.constants.Frames.IAU_MERCURY_FRAME} + + +##### Variable `IAU_MOON_FRAME` {#anise.constants.Frames.IAU_MOON_FRAME} + + +##### Variable `IAU_NEPTUNE_FRAME` {#anise.constants.Frames.IAU_NEPTUNE_FRAME} + + +##### Variable `IAU_SATURN_FRAME` {#anise.constants.Frames.IAU_SATURN_FRAME} + + +##### Variable `IAU_URANUS_FRAME` {#anise.constants.Frames.IAU_URANUS_FRAME} + + +##### Variable `IAU_VENUS_FRAME` {#anise.constants.Frames.IAU_VENUS_FRAME} + + +##### Variable `JUPITER_BARYCENTER_J2000` {#anise.constants.Frames.JUPITER_BARYCENTER_J2000} + + +##### Variable `MARS_BARYCENTER_J2000` {#anise.constants.Frames.MARS_BARYCENTER_J2000} + + +##### Variable `MERCURY_J2000` {#anise.constants.Frames.MERCURY_J2000} + + +##### Variable `MOON_J2000` {#anise.constants.Frames.MOON_J2000} + + +##### Variable `MOON_ME_DE421_FRAME` {#anise.constants.Frames.MOON_ME_DE421_FRAME} + + +##### Variable `MOON_ME_DE440_ME421_FRAME` {#anise.constants.Frames.MOON_ME_DE440_ME421_FRAME} + + +##### Variable `MOON_ME_FRAME` {#anise.constants.Frames.MOON_ME_FRAME} + + +##### Variable `MOON_PA_DE421_FRAME` {#anise.constants.Frames.MOON_PA_DE421_FRAME} + + +##### Variable `MOON_PA_DE440_FRAME` {#anise.constants.Frames.MOON_PA_DE440_FRAME} + + +##### Variable `MOON_PA_FRAME` {#anise.constants.Frames.MOON_PA_FRAME} + + +##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.constants.Frames.NEPTUNE_BARYCENTER_J2000} + + +##### Variable `PLUTO_BARYCENTER_J2000` {#anise.constants.Frames.PLUTO_BARYCENTER_J2000} + + +##### Variable `SATURN_BARYCENTER_J2000` {#anise.constants.Frames.SATURN_BARYCENTER_J2000} + + +##### Variable `SSB_J2000` {#anise.constants.Frames.SSB_J2000} + + +##### Variable `SUN_J2000` {#anise.constants.Frames.SUN_J2000} + + +##### Variable `URANUS_BARYCENTER_J2000` {#anise.constants.Frames.URANUS_BARYCENTER_J2000} + + +##### Variable `VENUS_J2000` {#anise.constants.Frames.VENUS_J2000} + + +### Class `Orientations` {#anise.constants.Orientations} + +> class Orientations( +> ... +> ) + + +#### Class variables + + +##### Variable `ECLIPJ2000` {#anise.constants.Orientations.ECLIPJ2000} + + +##### Variable `IAU_EARTH` {#anise.constants.Orientations.IAU_EARTH} + + +##### Variable `IAU_JUPITER` {#anise.constants.Orientations.IAU_JUPITER} + + +##### Variable `IAU_MARS` {#anise.constants.Orientations.IAU_MARS} + + +##### Variable `IAU_MERCURY` {#anise.constants.Orientations.IAU_MERCURY} + + +##### Variable `IAU_MOON` {#anise.constants.Orientations.IAU_MOON} + + +##### Variable `IAU_NEPTUNE` {#anise.constants.Orientations.IAU_NEPTUNE} + + +##### Variable `IAU_SATURN` {#anise.constants.Orientations.IAU_SATURN} + + +##### Variable `IAU_URANUS` {#anise.constants.Orientations.IAU_URANUS} + + +##### Variable `IAU_VENUS` {#anise.constants.Orientations.IAU_VENUS} + + +##### Variable `ITRF93` {#anise.constants.Orientations.ITRF93} + + +##### Variable `J2000` {#anise.constants.Orientations.J2000} + + +##### Variable `MOON_ME` {#anise.constants.Orientations.MOON_ME} + + +##### Variable `MOON_ME_DE421` {#anise.constants.Orientations.MOON_ME_DE421} + + +##### Variable `MOON_ME_DE440_ME421` {#anise.constants.Orientations.MOON_ME_DE440_ME421} + + +##### Variable `MOON_PA` {#anise.constants.Orientations.MOON_PA} + + +##### Variable `MOON_PA_DE421` {#anise.constants.Orientations.MOON_PA_DE421} + + +##### Variable `MOON_PA_DE440` {#anise.constants.Orientations.MOON_PA_DE440} + + +### Class `UsualConstants` {#anise.constants.UsualConstants} + +> class UsualConstants( +> ... +> ) + + +#### Class variables + + +##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S` {#anise.constants.UsualConstants.MEAN_EARTH_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S` {#anise.constants.UsualConstants.MEAN_MOON_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `SPEED_OF_LIGHT_KM_S` {#anise.constants.UsualConstants.SPEED_OF_LIGHT_KM_S} + +----- +Generated by *pdoc* 0.11.6 (). diff --git a/docs/anise/reference/api/python/index.md b/docs/anise/reference/api/python/index.md index b7d9203..4101db3 100644 --- a/docs/anise/reference/api/python/index.md +++ b/docs/anise/reference/api/python/index.md @@ -1,17 +1,19 @@ -# Module `anise` - -A Python module implemented in Rust. +# Module `anise` {#anise} ## Sub-modules -* [anise.anise](#anise.anise) +* [anise.astro](#anise.astro) +* [anise.constants](#anise.constants) +* [anise.rotation](#anise.rotation) +* [anise.time](#anise.time) +* [anise.utils](#anise.utils) ## Classes -### Class `Aberration` +### Class `Aberration` {#anise.Aberration} > class Aberration( > name @@ -35,62 +37,125 @@ For more details, validate\_jplde\_de440s\_aberration\_lt checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time. More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters. +:type name: str +:rtype: Aberration + #### Instance variables -##### Variable `converged` +##### Variable `converged` {#anise.Aberration.converged} -Indicates whether the light time calculations should be iterated upon (more precise but three times as many CPU cycles). +:rtype: bool -##### Variable `stellar` +##### Variable `stellar` {#anise.Aberration.stellar} -Flag to denote if stellar aberration correction is applied. Stellar aberration is due to the motion of the observer (caused by Earth's orbit around the Sun). +:rtype: bool -##### Variable `transmit_mode` +##### Variable `transmit_mode` {#anise.Aberration.transmit_mode} -Specifies whether in reception or transmission mode. True for 'transmit' mode, indicating the correction is applied to the transmitted signal from the observer to the target. False for 'receive' mode, for signals received from the target. +:rtype: bool -### Class `Almanac` +### Class `Almanac` {#anise.Almanac} > class Almanac( > path > ) -An Almanac contains all of the loaded SPICE and ANISE data. +An Almanac contains all of the loaded SPICE and ANISE data. It is the context for all computations. -### Limitations -The stack space required depends on the maximum number of each type that can be loaded. +:type path: str +:rtype: Almanac #### Methods -##### Method `azimuth_elevation_range_sez` +##### Method `azimuth_elevation_range_sez` {#anise.Almanac.azimuth_elevation_range_sez} > def azimuth_elevation_range_sez( > self, > /, > rx, -> tx +> tx, +> obstructing_body=None, +> ab_corr=None > ) Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the receiver state (rx) seen from the transmitter state (tx), once converted into the SEZ frame of the transmitter. +##### Warning +The obstructing body _should_ be a tri-axial ellipsoid body, e.g. IAU_MOON_FRAME. + ##### Algorithm -1. Compute the SEZ (South East Zenith) frame of the transmitter. -2. Rotate the receiver position vector into the transmitter SEZ frame. -3. Rotate the transmitter position vector into that same SEZ frame. -4. Compute the range as the norm of the difference between these two position vectors. -5. Compute the elevation, and ensure it is between +/- 180 degrees. -6. Compute the azimuth with a quadrant check, and ensure it is between 0 and 360 degrees. +1. If any obstructing_bodies are provided, ensure that none of these are obstructing the line of sight between the receiver and transmitter. +2. Compute the SEZ (South East Zenith) frame of the transmitter. +3. Rotate the receiver position vector into the transmitter SEZ frame. +4. Rotate the transmitter position vector into that same SEZ frame. +5. Compute the range as the norm of the difference between these two position vectors. +6. Compute the elevation, and ensure it is between +/- 180 degrees. +7. Compute the azimuth with a quadrant check, and ensure it is between 0 and 360 degrees. + +:type rx: Orbit +:type tx: Orbit +:type obstructing_body: Frame, optional +:type ab_corr: Aberration, optional +:rtype: AzElRange + + +##### Method `azimuth_elevation_range_sez_many` {#anise.Almanac.azimuth_elevation_range_sez_many} + +> def azimuth_elevation_range_sez_many( +> self, +> /, +> rx_tx_states, +> obstructing_body=None, +> ab_corr=None +> ) + +Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the +receiver states (first item in tuple) seen from the transmitter state (second item in states tuple), once converted into the SEZ frame of the transmitter. + +Note: if any computation fails, the error will be printed to the stderr. +Note: the output AER will be chronologically sorted, regardless of transmitter. + +Refer to [azimuth_elevation_range_sez] for details. + +:type rx_tx_states: typing.List[Orbit] +:type obstructing_body: Frame, optional +:type ab_corr: Aberration, optional +:rtype: typing.List[AzElRange] + + +##### Method `beta_angle_deg` {#anise.Almanac.beta_angle_deg} + +> def beta_angle_deg( +> self, +> /, +> state, +> ab_corr=None +> ) + +Computes the Beta angle (β) for a given orbital state, in degrees. A Beta angle of 0° indicates that the orbit plane is edge-on to the Sun, leading to maximum eclipse time. Conversely, a Beta angle of +90° or -90° means the orbit plane is face-on to the Sun, resulting in continuous sunlight exposure and no eclipses. + +The Beta angle (β) is defined as the angle between the orbit plane of a spacecraft and the vector from the central body (e.g., Earth) to the Sun. In simpler terms, it measures how much of the time a satellite in orbit is exposed to direct sunlight. +The mathematical formula for the Beta angle is: β=arcsin(h⋅usun​) +Where: +- h is the unit vector of the orbital momentum. +- usun​ is the unit vector pointing from the central body to the Sun. + +Original code from GMAT, + +:type state: Orbit +:type ab_corr: Aberration, optional +:rtype: float -##### Method `bpc_domain` +##### Method `bpc_domain` {#anise.Almanac.bpc_domain} > def bpc_domain( > self, @@ -100,8 +165,11 @@ receiver state (rx) seen from the transmitter state (tx def bpc_domains( > self, @@ -113,8 +181,10 @@ Returns a map of each loaded BPC ID to its domain validity. ##### Warning This function performs a memory allocation. +:rtype: typing.Dict + -##### Method `bpc_summaries` +##### Method `bpc_summaries` {#anise.Almanac.bpc_summaries} > def bpc_summaries( > self, @@ -124,8 +194,14 @@ This function performs a memory allocation. Returns a vector of the summaries whose ID matches the desired id, in the order in which they will be used, i.e. in reverse loading order. +##### Warning +This function performs a memory allocation. + +:type id: int +:rtype: typing.List + -##### Method `describe` +##### Method `describe` {#anise.Almanac.describe} > def describe( > self, @@ -133,6 +209,7 @@ Returns a vector of the summaries whose ID matches the desired id, > spk=None, > bpc=None, > planetary=None, +> eulerparams=None, > time_scale=None, > round_time=None > ) @@ -140,8 +217,16 @@ Returns a vector of the summaries whose ID matches the desired id, Pretty prints the description of this Almanac, showing everything by default. Default time scale is TDB. If any parameter is set to true, then nothing other than that will be printed. +:type spk: bool, optional +:type bpc: bool, optional +:type planetary: bool, optional +:type eulerparams: bool, optional +:type time_scale: TimeScale, optional +:type round_time: bool, optional +:rtype: None + -##### Method `frame_info` +##### Method `frame_info` {#anise.Almanac.frame_info} > def frame_info( > self, @@ -149,8 +234,59 @@ If any parameter is set to true, then nothing other than that will be printed. > uid > ) +Returns the frame information (gravitational param, shape) as defined in this Almanac from an empty frame +:type uid: Frame +:rtype: Frame + + +##### Method `line_of_sight_obstructed` {#anise.Almanac.line_of_sight_obstructed} + +> def line_of_sight_obstructed( +> self, +> /, +> observer, +> observed, +> obstructing_body, +> ab_corr=None +> ) + +Computes whether the line of sight between an observer and an observed Cartesian state is obstructed by the obstructing body. +Returns true if the obstructing body is in the way, false otherwise. + +For example, if the Moon is in between a Lunar orbiter (observed) and a ground station (observer), then this function returns true +because the Moon (obstructing body) is indeed obstructing the line of sight. + +```text +Observed + o - + + - + + - + + *** - + * + * - + * + + * + + o + * * Observer + **** +``` + +Key Elements: +- o represents the positions of the observer and observed objects. +- The dashed line connecting the observer and observed is the line of sight. + +Algorithm (source: Algorithm 35 of Vallado, 4th edition, page 308.): +- r1 and r2 are the transformed radii of the observed and observer objects, respectively. +- r1sq and r2sq are the squared magnitudes of these vectors. +- r1dotr2 is the dot product of r1 and r2. +- tau is a parameter that determines the intersection point along the line of sight. +- The condition `(1.0 - tau) * r1sq + r1dotr2 * tau <= ob_mean_eq_radius_km^2` checks if the line of sight is within the obstructing body's radius, indicating an obstruction. + +:type observer: Orbit +:type observed: Orbit +:type obstructing_body: Frame +:type ab_corr: Aberration, optional +:rtype: bool + -##### Method `load` +##### Method `load` {#anise.Almanac.load} > def load( > self, @@ -160,19 +296,139 @@ If any parameter is set to true, then nothing other than that will be printed. Generic function that tries to load the provided path guessing to the file type. +:type path: str +:rtype: Almanac + -##### Method `load_from_metafile` +##### Method `load_from_metafile` {#anise.Almanac.load_from_metafile} > def load_from_metafile( > self, > /, -> metafile +> metafile, +> autodelete > ) Load from the provided MetaFile, downloading it if necessary. +Set autodelete to true to automatically delete lock files. Lock files are important in multi-threaded loads. + +:type metafile: MetaFile +:type autodelete: bool +:rtype: Almanac + + +##### Method `occultation` {#anise.Almanac.occultation} + +> def occultation( +> self, +> /, +> back_frame, +> front_frame, +> observer, +> ab_corr=None +> ) + +Computes the occultation percentage of the back\_frame object by the front\_frame object as seen from the observer, when according for the provided aberration correction. + +A zero percent occultation means that the back object is fully visible from the observer. +A 100% percent occultation means that the back object is fully hidden from the observer because of the front frame (i.e. _umbra_ if the back object is the Sun). +A value in between means that the back object is partially hidden from the observser (i.e. _penumbra_ if the back object is the Sun). +Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details. + +:type back_frame: Frame +:type front_frame: Frame +:type observer: Orbit +:type ab_corr: Aberration, optional +:rtype: Occultation + + +##### Method `rotate` {#anise.Almanac.rotate} + +> def rotate( +> self, +> /, +> from_frame, +> to_frame, +> epoch +> ) + +Returns the 6x6 DCM needed to rotation the from\_frame to the to\_frame. + +##### Warning +This function only performs the rotation and no translation whatsoever. Use the transform\_from\_to function instead to include rotations. + +##### Note +This function performs a recursion of no more than twice the MAX_TREE_DEPTH. + +:type from_frame: Frame +:type to_frame: Frame +:type epoch: Epoch +:rtype: DCM + + +##### Method `rotate_to` {#anise.Almanac.rotate_to} + +> def rotate_to( +> self, +> /, +> state, +> observer_frame +> ) + +Rotates the provided Cartesian state into the requested observer frame + +**WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the transform\_to function instead to include rotations. + +:type state: Orbit +:type observer_frame: Frame +:rtype: Orbit + + +##### Method `solar_eclipsing` {#anise.Almanac.solar_eclipsing} + +> def solar_eclipsing( +> self, +> /, +> eclipsing_frame, +> observer, +> ab_corr=None +> ) + +Computes the solar eclipsing of the observer due to the eclipsing_frame. + +This function calls occultation where the back object is the Sun in the J2000 frame, and the front object +is the provided eclipsing frame. + +:type eclipsing_frame: Frame +:type observer: Orbit +:type ab_corr: Aberration, optional +:rtype: Occultation + + +##### Method `solar_eclipsing_many` {#anise.Almanac.solar_eclipsing_many} + +> def solar_eclipsing_many( +> self, +> /, +> eclipsing_frame, +> observers, +> ab_corr=None +> ) + +Computes the solar eclipsing of all the observers due to the eclipsing_frame, computed in parallel under the hood. + +Note: if any computation fails, the error will be printed to the stderr. +Note: the output AER will be chronologically sorted, regardless of transmitter. + +Refer to [solar_eclipsing] for details. + +:type eclipsing_frame: Frame +:type observers: typing.List[Orbit] +:type ab_corr: Aberration, optional +:rtype: typing.List[Occultation] -##### Method `spk_domain` +##### Method `spk_domain` {#anise.Almanac.spk_domain} > def spk_domain( > self, @@ -182,8 +438,11 @@ Load from the provided MetaFile, downloading it if necessary. Returns the applicable domain of the request id, i.e. start and end epoch that the provided id has loaded data. +:type id: int +:rtype: typing.Tuple + -##### Method `spk_domains` +##### Method `spk_domains` {#anise.Almanac.spk_domains} > def spk_domains( > self, @@ -195,8 +454,32 @@ Returns a map of each loaded SPK ID to its domain validity. ##### Warning This function performs a memory allocation. +:rtype: typing.Dict + + +##### Method `spk_ezr` {#anise.Almanac.spk_ezr} + +> def spk_ezr( +> self, +> /, +> target, +> epoch, +> frame, +> observer, +> ab_corr=None +> ) + +Alias fo SPICE's spkezr where the inputs must be the NAIF IDs of the objects and frames with the caveat that the aberration is moved to the last positional argument. + +:type target: int +:type epoch: Epoch +:type frame: int +:type observer: int +:type ab_corr: Aberration, optional +:rtype: Orbit + -##### Method `spk_summaries` +##### Method `spk_summaries` {#anise.Almanac.spk_summaries} > def spk_summaries( > self, @@ -209,13 +492,16 @@ Returns a vector of the summaries whose ID matches the desired id, ##### Warning This function performs a memory allocation. +:type id: int +:rtype: typing.List + -##### Method `state_of` +##### Method `state_of` {#anise.Almanac.state_of} > def state_of( > self, > /, -> object, +> object_id, > observer, > epoch, > ab_corr=None @@ -226,8 +512,14 @@ Returns the Cartesian state of the object as seen from the provided observer fra ##### Note The units will be those of the underlying ephemeris data (typically km and km/s) +:type object_id: int +:type observer: Frame +:type epoch: Epoch +:type ab_corr: Aberration, optional +:rtype: Orbit + -##### Method `sun_angle_deg` +##### Method `sun_angle_deg` {#anise.Almanac.sun_angle_deg} > def sun_angle_deg( > self, @@ -274,8 +566,13 @@ Sun 2. Compute the position of the target as seen from the observer 3. Return the arccosine of the dot product of the norms of these vectors. +:type target_id: int +:type observer_id: int +:type epoch: Epoch +:rtype: float + -##### Method `sun_angle_deg_from_frame` +##### Method `sun_angle_deg_from_frame` {#anise.Almanac.sun_angle_deg_from_frame} > def sun_angle_deg_from_frame( > self, @@ -287,8 +584,13 @@ Sun Convenience function that calls sun\_angle\_deg with the provided frames instead of the ephemeris ID. +:type target: Frame +:type observer: Frame +:type epoch: Epoch +:rtype: float + -##### Method `transform` +##### Method `transform` {#anise.Almanac.transform} > def transform( > self, @@ -312,8 +614,59 @@ will return exactly the same data as the spkerz SPICE call. ##### Note The units will be those of the underlying ephemeris data (typically km and km/s) +:type target_frame: Orbit +:type observer_frame: Frame +:type epoch: Epoch +:type ab_corr: Aberration, optional +:rtype: Orbit + + +##### Method `transform_many` {#anise.Almanac.transform_many} + +> def transform_many( +> self, +> /, +> target_frame, +> observer_frame, +> time_series, +> ab_corr=None +> ) + +Returns a chronologically sorted list of the Cartesian states that transform the from\_frame to the to\_frame for each epoch of the time series, computed in parallel under the hood. +Note: if any transformation fails, the error will be printed to the stderr. + +Refer to [transform] for details. + +:type target_frame: Orbit +:type observer_frame: Frame +:type time_series: TimeSeries +:type ab_corr: Aberration, optional +:rtype: typing.List[Orbit] + + +##### Method `transform_many_to` {#anise.Almanac.transform_many_to} + +> def transform_many_to( +> self, +> /, +> states, +> observer_frame, +> ab_corr=None +> ) + +Returns a chronologically sorted list of the provided states as seen from the observer frame, given the aberration. +Note: if any transformation fails, the error will be printed to the stderr. +Note: the input ordering is lost: the output states will not be in the same order as the input states if these are not chronologically sorted! + +Refer to [transform_to] for details. + +:type states: typing.List[Orbit] +:type observer_frame: Frame +:type ab_corr: Aberration, optional +:rtype: typing.List[Orbit] + -##### Method `transform_to` +##### Method `transform_to` {#anise.Almanac.transform_to} > def transform_to( > self, @@ -323,12 +676,15 @@ The units will be those of the underlying ephemeris data (typically km and km/s) > ab_corr=None > ) -Translates a state with its origin (to\_frame) and given its units (distance_unit, time_unit), returns that state with respect to the requested frame +Returns the provided state as seen from the observer frame, given the aberration. -**WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the transform\_state\_to function instead to include rotations. +:type state: Orbit +:type observer_frame: Frame +:type ab_corr: Aberration, optional +:rtype: Orbit -##### Method `translate` +##### Method `translate` {#anise.Almanac.translate} > def translate( > self, @@ -355,8 +711,14 @@ This function only performs the translation and no rotation whatsoever. Use the ##### Note This function performs a recursion of no more than twice the [MAX_TREE_DEPTH]. +:type target_frame: Orbit +:type observer_frame: Frame +:type epoch: Epoch +:type ab_corr: Aberration, optional +:rtype: Orbit + -##### Method `translate_geometric` +##### Method `translate_geometric` {#anise.Almanac.translate_geometric} > def translate_geometric( > self, @@ -368,8 +730,13 @@ This function performs a recursion of no more than twice the [MAX_TREE_DEPTH]. Returns the geometric position vector, velocity vector, and acceleration vector needed to translate the from\_frame to the to\_frame, where the distance is in km, the velocity in km/s, and the acceleration in km/s^2. +:type target_frame: Orbit +:type observer_frame: Frame +:type epoch: Epoch +:rtype: Orbit + -##### Method `translate_to` +##### Method `translate_to` {#anise.Almanac.translate_to} > def translate_to( > self, @@ -383,8 +750,13 @@ Translates the provided Cartesian state into the requested observer frame **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the transform\_to function instead to include rotations. +:type state: Orbit +:type observer_frame: Frame +:type ab_corr: Aberration, optional +:rtype: Orbit + -##### Method `translate_to_parent` +##### Method `translate_to_parent` {#anise.Almanac.translate_to_parent} > def translate_to_parent( > self, @@ -395,8 +767,12 @@ Translates the provided Cartesian state into the requested observer frame Performs the GEOMETRIC translation to the parent. Use translate_from_to for aberration. +:type source: Frame +:type epoch: Epoch +:rtype: Orbit + -### Class `MetaAlmanac` +### Class `MetaAlmanac` {#anise.MetaAlmanac} > class MetaAlmanac( > maybe_path=None @@ -410,19 +786,22 @@ If the URI is a remote path, the MetaAlmanac will first check if the file exists If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file. The downloaded path will be stored in the "AppData" folder. +:type maybe_path: str, optional +:rtype: MetaAlmanac + #### Instance variables -##### Variable `files` +##### Variable `files` {#anise.MetaAlmanac.files} -Return an attribute of instance, which is of type owner. +:rtype: typing.List #### Methods -##### Method `dumps` +##### Method `dumps` {#anise.MetaAlmanac.dumps} > def dumps( > self, @@ -431,17 +810,21 @@ Return an attribute of instance, which is of type owner. Dumps the configured Meta Almanac into a Dhall string. +:rtype: str + -##### Method `latest` +##### Method `latest` {#anise.MetaAlmanac.latest} -> def latest() +> def latest( +> autodelete=None +> ) Returns an Almanac loaded from the latest NAIF data via the default MetaAlmanac. The MetaAlmanac will download the DE440s.bsp file, the PCK0008.PCA, the full Moon Principal Axis BPC (moon_pa_de440_200625) and the latest high precision Earth kernel from JPL. ##### File list - -- +- - - @@ -450,8 +833,13 @@ The MetaAlmanac will download the DE440s.bsp file, the PCK0008.PCA, the full Moo Note that the earth\_latest\_high\_prec.bpc file is regularly updated daily (or so). As such, if queried at some future time, the Earth rotation parameters may have changed between two queries. +Set autodelete to true to delete lock file if a dead lock is detected after 10 seconds. + +:type autodelete: bool, optional +:rtype: MetaAlmanac + -##### Method `loads` +##### Method `loads` {#anise.MetaAlmanac.loads} > def loads( > s @@ -459,18 +847,29 @@ if queried at some future time, the Earth rotation parameters may have changed b Loads the provided string as a Dhall configuration to build a MetaAlmanac +:type s: str +:rtype: MetaAlmanac + -##### Method `process` +##### Method `process` {#anise.MetaAlmanac.process} > def process( > self, -> / +> /, +> autodelete=None > ) -Fetch all of the URIs and return a loaded Almanac +Fetch all of the URIs and return a loaded Almanac. +When downloading the data, ANISE will create a temporarily lock file to prevent race conditions +where multiple processes download the data at the same time. Set autodelete to true to delete +this lock file if a dead lock is detected after 10 seconds. Set this flag to false if you have +more than ten processes which may attempt to download files in parallel. + +:type autodelete: bool, optional +:rtype: Almanac -### Class `MetaFile` +### Class `MetaFile` {#anise.MetaFile} > class MetaFile( > uri, @@ -483,542 +882,6093 @@ The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx- Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile, then the file will not be downloaded a second time. +:type uri: str +:type crc32: int, optional +:rtype: MetaFile + #### Instance variables -##### Variable `crc32` +##### Variable `crc32` {#anise.MetaFile.crc32} -Optionally specify the CRC32 of this file, which will be checked prior to loading. +:rtype: int -##### Variable `uri` +##### Variable `uri` {#anise.MetaFile.uri} -URI of this meta file +:rtype: str #### Methods -##### Method `process` +##### Method `process` {#anise.MetaFile.process} > def process( > self, -> / +> /, +> autodelete=None > ) Processes this MetaFile by downloading it if it's a URL. This function modified self and changes the URI to be the path to the downloaded file. +:type autodelete: bool, optional +:rtype: None + + +# Module `anise.astro` {#anise.astro} + -# Module `anise.anise` +## Sub-modules -A Python module implemented in Rust. +* [anise.astro.constants](#anise.astro.constants) ## Classes -### Class `Aberration` +### Class `AzElRange` {#anise.astro.AzElRange} -> class Aberration( -> name +> class AzElRange( +> epoch, +> azimuth_deg, +> elevation_deg, +> range_km, +> range_rate_km_s, +> obstructed_by=None > ) -Represents the aberration correction options in ANISE. - -In space science and engineering, accurately pointing instruments (like optical cameras or radio antennas) at a target is crucial. This task is complicated by the finite speed of light, necessitating corrections for the apparent position of the target. - -This structure holds parameters for aberration corrections applied to a target's position or state vector. These corrections account for the difference between the target's geometric (true) position and its apparent position as observed. +A structure that stores the result of Azimuth, Elevation, Range, Range rate calculation. -### Rule of tumb -In most Earth orbits, one does _not_ need to provide any aberration corrections. Light time to the target is less than one second (the Moon is about one second away). -In near Earth orbits, e.g. inner solar system, preliminary analysis can benefit from enabling unconverged light time correction. Stellar aberration is probably not required. -For deep space missions, preliminary analysis would likely require both light time correction and stellar aberration. Mission planning and operations will definitely need converged light-time calculations. +:type epoch: Epoch +:type azimuth_deg: float +:type elevation_deg: float +:type range_km: float +:type range_rate_km_s: float +:type obstructed_by: Frame, optional +:rtype: AzElRange -For more details, . + +#### Instance variables -### SPICE Validation + +##### Variable `azimuth_deg` {#anise.astro.AzElRange.azimuth_deg} -The validation test validate\_jplde\_de440s\_aberration\_lt checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time. -More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters. +:rtype: float -#### Instance variables +##### Variable `elevation_deg` {#anise.astro.AzElRange.elevation_deg} + +:rtype: float -##### Variable `converged` +##### Variable `epoch` {#anise.astro.AzElRange.epoch} -Indicates whether the light time calculations should be iterated upon (more precise but three times as many CPU cycles). +:rtype: Epoch -##### Variable `stellar` +##### Variable `light_time` {#anise.astro.AzElRange.light_time} -Flag to denote if stellar aberration correction is applied. Stellar aberration is due to the motion of the observer (caused by Earth's orbit around the Sun). +:rtype: Duration -##### Variable `transmit_mode` +##### Variable `obstructed_by` {#anise.astro.AzElRange.obstructed_by} -Specifies whether in reception or transmission mode. True for 'transmit' mode, indicating the correction is applied to the transmitted signal from the observer to the target. False for 'receive' mode, for signals received from the target. +:rtype: Frame -### Class `Almanac` +##### Variable `range_km` {#anise.astro.AzElRange.range_km} -> class Almanac( -> path -> ) +:rtype: float -An Almanac contains all of the loaded SPICE and ANISE data. + +##### Variable `range_rate_km_s` {#anise.astro.AzElRange.range_rate_km_s} -### Limitations -The stack space required depends on the maximum number of each type that can be loaded. +:rtype: float #### Methods -##### Method `azimuth_elevation_range_sez` +##### Method `is_obstructed` {#anise.astro.AzElRange.is_obstructed} -> def azimuth_elevation_range_sez( +> def is_obstructed( > self, -> /, -> rx, -> tx +> / > ) -Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the -receiver state (rx) seen from the transmitter state (tx), once converted into the SEZ frame of the transmitter. +Returns whether there is an obstruction. -##### Algorithm -1. Compute the SEZ (South East Zenith) frame of the transmitter. -2. Rotate the receiver position vector into the transmitter SEZ frame. -3. Rotate the transmitter position vector into that same SEZ frame. -4. Compute the range as the norm of the difference between these two position vectors. -5. Compute the elevation, and ensure it is between +/- 180 degrees. -6. Compute the azimuth with a quadrant check, and ensure it is between 0 and 360 degrees. +:rtype: bool -##### Method `bpc_domain` +##### Method `is_valid` {#anise.astro.AzElRange.is_valid} -> def bpc_domain( +> def is_valid( > self, -> /, -> id +> / > ) -Returns the applicable domain of the request id, i.e. start and end epoch that the provided id has loaded data. +Returns false if the range is less than one millimeter, or any of the angles are NaN. + +:rtype: bool -##### Method `bpc_domains` +### Class `Ellipsoid` {#anise.astro.Ellipsoid} -> def bpc_domains( -> self, -> / +> class Ellipsoid( +> semi_major_equatorial_radius_km, +> polar_radius_km=None, +> semi_minor_equatorial_radius_km=None > ) -Returns a map of each loaded BPC ID to its domain validity. +Only the tri-axial Ellipsoid shape model is currently supported by ANISE. +This is directly inspired from SPICE PCK. +> For each body, three radii are listed: The first number is +> the largest equatorial radius (the length of the semi-axis +> containing the prime meridian), the second number is the smaller +> equatorial radius, and the third is the polar radius. -##### Warning -This function performs a memory allocation. +Example: Radii of the Earth. + + BODY399_RADII = ( 6378.1366 6378.1366 6356.7519 ) + +:type semi_major_equatorial_radius_km: float +:type polar_radius_km: float, optional +:type semi_minor_equatorial_radius_km: float, optional +:rtype: Ellipsoid -##### Method `bpc_summaries` +#### Instance variables -> def bpc_summaries( -> self, -> /, -> id -> ) + +##### Variable `polar_radius_km` {#anise.astro.Ellipsoid.polar_radius_km} -Returns a vector of the summaries whose ID matches the desired id, in the order in which they will be used, i.e. in reverse loading order. +:rtype: float -##### Method `describe` +##### Variable `semi_major_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_major_equatorial_radius_km} -> def describe( -> self, -> /, -> spk=None, -> bpc=None, -> planetary=None, -> time_scale=None, -> round_time=None -> ) +:rtype: float -Pretty prints the description of this Almanac, showing everything by default. Default time scale is TDB. -If any parameter is set to true, then nothing other than that will be printed. + +##### Variable `semi_minor_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_minor_equatorial_radius_km} + +:rtype: float -##### Method `frame_info` +#### Methods -> def frame_info( + +##### Method `flattening` {#anise.astro.Ellipsoid.flattening} + +> def flattening( > self, -> /, -> uid +> / > ) +Returns the flattening ratio, computed from the mean equatorial radius and the polar radius + +:rtype: float + -##### Method `load` +##### Method `is_sphere` {#anise.astro.Ellipsoid.is_sphere} -> def load( +> def is_sphere( > self, -> /, -> path +> / > ) -Generic function that tries to load the provided path guessing to the file type. +Returns true if the polar radius is equal to the semi minor radius. + +:rtype: bool -##### Method `load_from_metafile` +##### Method `is_spheroid` {#anise.astro.Ellipsoid.is_spheroid} -> def load_from_metafile( +> def is_spheroid( +> self, +> / +> ) + +Returns true if the semi major and minor radii are equal + +:rtype: bool + + +##### Method `mean_equatorial_radius_km` {#anise.astro.Ellipsoid.mean_equatorial_radius_km} + +> def mean_equatorial_radius_km( +> self, +> / +> ) + +Returns the mean equatorial radius in kilometers + +:rtype: float + + +### Class `Frame` {#anise.astro.Frame} + +> class Frame( +> ephemeris_id, +> orientation_id, +> mu_km3_s2=None, +> shape=None +> ) + +A Frame uniquely defined by its ephemeris center and orientation. Refer to FrameDetail for frames combined with parameters. + +:type ephemeris_id: int +:type orientation_id: int +:type mu_km3_s2: float, optional +:type shape: Ellipsoid, optional +:rtype: Frame + + +#### Instance variables + + +##### Variable `ephemeris_id` {#anise.astro.Frame.ephemeris_id} + +:rtype: int + + +##### Variable `orientation_id` {#anise.astro.Frame.orientation_id} + +:rtype: int + + +##### Variable `shape` {#anise.astro.Frame.shape} + +:rtype: Ellipsoid + + +#### Methods + + +##### Method `ephem_origin_id_match` {#anise.astro.Frame.ephem_origin_id_match} + +> def ephem_origin_id_match( > self, > /, -> metafile +> other_id > ) -Load from the provided MetaFile, downloading it if necessary. +Returns true if the ephemeris origin is equal to the provided ID + +:type other_id: int +:rtype: bool -##### Method `spk_domain` +##### Method `ephem_origin_match` {#anise.astro.Frame.ephem_origin_match} -> def spk_domain( +> def ephem_origin_match( > self, > /, -> id +> other > ) -Returns the applicable domain of the request id, i.e. start and end epoch that the provided id has loaded data. +Returns true if the ephemeris origin is equal to the provided frame + +:type other: Frame +:rtype: bool -##### Method `spk_domains` +##### Method `flattening` {#anise.astro.Frame.flattening} -> def spk_domains( +> def flattening( > self, > / > ) -Returns a map of each loaded SPK ID to its domain validity. +Returns the flattening ratio (unitless) -##### Warning -This function performs a memory allocation. +:rtype: float -##### Method `spk_summaries` +##### Method `is_celestial` {#anise.astro.Frame.is_celestial} -> def spk_summaries( +> def is_celestial( > self, -> /, -> id +> / > ) -Returns a vector of the summaries whose ID matches the desired id, in the order in which they will be used, i.e. in reverse loading order. +Returns whether this is a celestial frame -##### Warning -This function performs a memory allocation. +:rtype: bool -##### Method `state_of` +##### Method `is_geodetic` {#anise.astro.Frame.is_geodetic} -> def state_of( +> def is_geodetic( > self, -> /, -> object, -> observer, -> epoch, -> ab_corr=None +> / > ) -Returns the Cartesian state of the object as seen from the provided observer frame (essentially spkezr). +Returns whether this is a geodetic frame -##### Note -The units will be those of the underlying ephemeris data (typically km and km/s) +:rtype: bool -##### Method `sun_angle_deg` +##### Method `mean_equatorial_radius_km` {#anise.astro.Frame.mean_equatorial_radius_km} -> def sun_angle_deg( +> def mean_equatorial_radius_km( > self, -> /, -> target_id, -> observer_id, -> epoch +> / > ) -Returns the angle (between 0 and 180 degrees) between the observer and the Sun, and the observer and the target body ID. -This computes the Sun Probe Earth angle (SPE) if the probe is in a loaded SPK, its ID is the "observer_id", and the target is set to its central body. +Returns the mean equatorial radius in km, if defined -##### Geometry -If the SPE is greater than 90 degrees, then the celestial object below the probe is in sunlight. +:rtype: float -###### Sunrise at nadir -```text -Sun - | \ - | \ - | \ - Obs. -- Target -``` -###### Sun high at nadir -```text -Sun - \ - \ __ θ > 90 - \ \ - Obs. ---------- Target -``` + +##### Method `mu_km3_s2` {#anise.astro.Frame.mu_km3_s2} -###### Sunset at nadir -```text - Sun - / - / __ θ < 90 - / / - Obs. -- Target -``` +> def mu_km3_s2( +> self, +> / +> ) -##### Algorithm -1. Compute the position of the Sun as seen from the observer -2. Compute the position of the target as seen from the observer -3. Return the arccosine of the dot product of the norms of these vectors. +Returns the gravitational parameters of this frame, if defined + +:rtype: float -##### Method `sun_angle_deg_from_frame` +##### Method `orient_origin_id_match` {#anise.astro.Frame.orient_origin_id_match} -> def sun_angle_deg_from_frame( +> def orient_origin_id_match( > self, > /, -> target, -> observer, -> epoch +> other_id > ) -Convenience function that calls sun\_angle\_deg with the provided frames instead of the ephemeris ID. +Returns true if the orientation origin is equal to the provided ID + +:type other_id: int +:rtype: bool -##### Method `transform` +##### Method `orient_origin_match` {#anise.astro.Frame.orient_origin_match} -> def transform( +> def orient_origin_match( > self, > /, -> target_frame, -> observer_frame, -> epoch, -> ab_corr=None +> other > ) -Returns the Cartesian state needed to transform the from\_frame to the to\_frame. - -##### SPICE Compatibility -This function is the SPICE equivalent of spkezr: spkezr(TARGET\_ID, EPOCH\_TDB\_S, ORIENTATION\_ID, ABERRATION, OBSERVER\_ID) -In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH -the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed -in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER -argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call -will return exactly the same data as the spkerz SPICE call. +Returns true if the orientation origin is equal to the provided frame -##### Note -The units will be those of the underlying ephemeris data (typically km and km/s) +:type other: Frame +:rtype: bool -##### Method `transform_to` +##### Method `polar_radius_km` {#anise.astro.Frame.polar_radius_km} -> def transform_to( +> def polar_radius_km( > self, -> /, -> state, -> observer_frame, -> ab_corr=None +> / > ) -Translates a state with its origin (to\_frame) and given its units (distance_unit, time_unit), returns that state with respect to the requested frame +Returns the polar radius in km, if defined -**WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the transform\_state\_to function instead to include rotations. +:rtype: float -##### Method `translate` +##### Method `semi_major_radius_km` {#anise.astro.Frame.semi_major_radius_km} -> def translate( +> def semi_major_radius_km( > self, -> /, -> target_frame, -> observer_frame, -> epoch, -> ab_corr=None +> / > ) -Returns the Cartesian state of the target frame as seen from the observer frame at the provided epoch, and optionally given the aberration correction. +Returns the semi major radius of the tri-axial ellipoid shape of this frame, if defined -##### SPICE Compatibility -This function is the SPICE equivalent of spkezr: spkezr(TARGET\_ID, EPOCH\_TDB\_S, ORIENTATION\_ID, ABERRATION, OBSERVER\_ID) -In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH -the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed -in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER -argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call -will return exactly the same data as the spkerz SPICE call. +:rtype: float -##### Warning -This function only performs the translation and no rotation whatsoever. Use the transform function instead to include rotations. + +##### Method `strip` {#anise.astro.Frame.strip} -##### Note -This function performs a recursion of no more than twice the [MAX_TREE_DEPTH]. +> def strip( +> self, +> / +> ) + +Removes the graviational parameter and the shape information from this frame. +Use this to prevent astrodynamical computations. + +:rtype: None -##### Method `translate_geometric` +##### Method `with_ephem` {#anise.astro.Frame.with_ephem} -> def translate_geometric( +> def with_ephem( > self, > /, -> target_frame, -> observer_frame, -> epoch +> new_ephem_id > ) -Returns the geometric position vector, velocity vector, and acceleration vector needed to translate the from\_frame to the to\_frame, where the distance is in km, the velocity in km/s, and the acceleration in km/s^2. +Returns a copy of this Frame whose ephemeris ID is set to the provided ID + +:type new_ephem_id: int +:rtype: Frame -##### Method `translate_to` +##### Method `with_mu_km3_s2` {#anise.astro.Frame.with_mu_km3_s2} -> def translate_to( +> def with_mu_km3_s2( > self, > /, -> state, -> observer_frame, -> ab_corr=None +> mu_km3_s2 > ) -Translates the provided Cartesian state into the requested observer frame +Returns a copy of this frame with the graviational parameter set to the new value. -**WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the transform\_to function instead to include rotations. +:type mu_km3_s2: float +:rtype: Frame -##### Method `translate_to_parent` +##### Method `with_orient` {#anise.astro.Frame.with_orient} -> def translate_to_parent( +> def with_orient( > self, > /, -> source, -> epoch +> new_orient_id > ) -Performs the GEOMETRIC translation to the parent. Use translate_from_to for aberration. +Returns a copy of this Frame whose orientation ID is set to the provided ID + +:type new_orient_id: int +:rtype: Frame -### Class `MetaAlmanac` +### Class `Occultation` {#anise.astro.Occultation} -> class MetaAlmanac( -> maybe_path=None +> class Occultation( +> ... > ) -A structure to set up an Almanac, with automatic downloading, local storage, checksum checking, and more. - -### Behavior -If the URI is a local path, relative or absolute, nothing will be fetched from a remote. Relative paths are relative to the execution folder (i.e. the current working directory). -If the URI is a remote path, the MetaAlmanac will first check if the file exists locally. If it exists, it will check that the CRC32 checksum of this file matches that of the specs. -If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file. -The downloaded path will be stored in the "AppData" folder. +Stores the result of an occultation computation with the occulation percentage +Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details. #### Instance variables -##### Variable `files` +##### Variable `back_frame` {#anise.astro.Occultation.back_frame} + +:rtype: Frame + + +##### Variable `epoch` {#anise.astro.Occultation.epoch} + +:rtype: Epoch + + +##### Variable `front_frame` {#anise.astro.Occultation.front_frame} -Return an attribute of instance, which is of type owner. +:rtype: Frame + + +##### Variable `percentage` {#anise.astro.Occultation.percentage} + +:rtype: float #### Methods -##### Method `dumps` +##### Method `factor` {#anise.astro.Occultation.factor} -> def dumps( +> def factor( > self, > / > ) -Dumps the configured Meta Almanac into a Dhall string. +Returns the percentage as a factor between 0 and 1 + +:rtype: float -##### Method `latest` +##### Method `is_eclipse_computation` {#anise.astro.Occultation.is_eclipse_computation} -> def latest() +> def is_eclipse_computation( +> self, +> / +> ) -Returns an Almanac loaded from the latest NAIF data via the default MetaAlmanac. -The MetaAlmanac will download the DE440s.bsp file, the PCK0008.PCA, the full Moon Principal Axis BPC (moon_pa_de440_200625) and the latest high precision Earth kernel from JPL. +Returns true if the back object is the Sun, false otherwise -##### File list -- -- -- -- +:rtype: bool -##### Reproducibility + +##### Method `is_obstructed` {#anise.astro.Occultation.is_obstructed} -Note that the earth\_latest\_high\_prec.bpc file is regularly updated daily (or so). As such, -if queried at some future time, the Earth rotation parameters may have changed between two queries. +> def is_obstructed( +> self, +> / +> ) + +Returns true if the occultation percentage is greater than or equal 99.999% + +:rtype: bool -##### Method `loads` +##### Method `is_partial` {#anise.astro.Occultation.is_partial} -> def loads( -> s +> def is_partial( +> self, +> / > ) -Loads the provided string as a Dhall configuration to build a MetaAlmanac +Returns true if neither occulted nor visible (i.e. penumbra for solar eclipsing) + +:rtype: bool -##### Method `process` +##### Method `is_visible` {#anise.astro.Occultation.is_visible} -> def process( +> def is_visible( > self, > / > ) -Fetch all of the URIs and return a loaded Almanac +Returns true if the occultation percentage is less than or equal 0.001% - -### Class `MetaFile` +:rtype: bool -> class MetaFile( -> uri, -> crc32=None + +### Class `Orbit` {#anise.astro.Orbit} + +> class Orbit( +> x_km, +> y_km, +> z_km, +> vx_km_s, +> vy_km_s, +> vz_km_s, +> epoch, +> frame > ) -MetaFile allows downloading a remote file from a URL (http, https only), and interpolation of paths in environment variable using the Dhall syntax `env:MY_ENV_VAR`. +Defines a Cartesian state in a given frame at a given epoch in a given time scale. Radius data is expressed in kilometers. Velocity data is expressed in kilometers per second. +Regardless of the constructor used, this struct stores all the state information in Cartesian coordinates as these are always non singular. -The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx-space/anise/` on Linux and `AppData/Local/nyx-space/anise/` on Windows). -Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile, -then the file will not be downloaded a second time. +Unless noted otherwise, algorithms are from GMAT 2016a [StateConversionUtil.cpp](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/util/StateConversionUtil.cpp). + +:type x_km: float +:type y_km: float +:type z_km: float +:type vx_km_s: float +:type vy_km_s: float +:type vz_km_s: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit #### Instance variables -##### Variable `crc32` +##### Variable `epoch` {#anise.astro.Orbit.epoch} -Optionally specify the CRC32 of this file, which will be checked prior to loading. +:rtype: Epoch -##### Variable `uri` +##### Variable `frame` {#anise.astro.Orbit.frame} -URI of this meta file +:rtype: Frame -#### Methods +##### Variable `vx_km_s` {#anise.astro.Orbit.vx_km_s} + +:rtype: float -##### Method `process` +##### Variable `vy_km_s` {#anise.astro.Orbit.vy_km_s} -> def process( -> self, -> / -> ) +:rtype: float -Processes this MetaFile by downloading it if it's a URL. + +##### Variable `vz_km` {#anise.astro.Orbit.vz_km} -This function modified self and changes the URI to be the path to the downloaded file. +:type vz_km_s: float +:rtype: None + + +##### Variable `vz_km_s` {#anise.astro.Orbit.vz_km_s} + +:rtype: float + + +##### Variable `x_km` {#anise.astro.Orbit.x_km} + +:rtype: float + + +##### Variable `y_km` {#anise.astro.Orbit.y_km} + +:rtype: float + + +##### Variable `z_km` {#anise.astro.Orbit.z_km} + +:rtype: float + + +#### Methods + + +##### Method `abs_difference` {#anise.astro.Orbit.abs_difference} + +> def abs_difference( +> self, +> /, +> other +> ) + +Returns the absolute position and velocity differences in km and km/s between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: typing.Tuple + + +##### Method `abs_pos_diff_km` {#anise.astro.Orbit.abs_pos_diff_km} + +> def abs_pos_diff_km( +> self, +> /, +> other +> ) + +Returns the absolute position difference in kilometer between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `abs_vel_diff_km_s` {#anise.astro.Orbit.abs_vel_diff_km_s} + +> def abs_vel_diff_km_s( +> self, +> /, +> other +> ) + +Returns the absolute velocity difference in kilometer per second between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `add_aop_deg` {#anise.astro.Orbit.add_aop_deg} + +> def add_aop_deg( +> self, +> /, +> delta_aop_deg +> ) + +Returns a copy of the state with a provided AOP added to the current one + +:type delta_aop_deg: float +:rtype: Orbit + + +##### Method `add_apoapsis_periapsis_km` {#anise.astro.Orbit.add_apoapsis_periapsis_km} + +> def add_apoapsis_periapsis_km( +> self, +> /, +> delta_ra_km, +> delta_rp_km +> ) + +Returns a copy of this state with the provided apoasis and periapsis added to the current values + +:type delta_ra_km: float +:type delta_rp_km: float +:rtype: Orbit + + +##### Method `add_ecc` {#anise.astro.Orbit.add_ecc} + +> def add_ecc( +> self, +> /, +> delta_ecc +> ) + +Returns a copy of the state with a provided ECC added to the current one + +:type delta_ecc: float +:rtype: Orbit + + +##### Method `add_inc_deg` {#anise.astro.Orbit.add_inc_deg} + +> def add_inc_deg( +> self, +> /, +> delta_inc_deg +> ) + +Returns a copy of the state with a provided INC added to the current one + +:type delta_inc_deg: float +:rtype: None + + +##### Method `add_raan_deg` {#anise.astro.Orbit.add_raan_deg} + +> def add_raan_deg( +> self, +> /, +> delta_raan_deg +> ) + +Returns a copy of the state with a provided RAAN added to the current one + +:type delta_raan_deg: float +:rtype: Orbit + + +##### Method `add_sma_km` {#anise.astro.Orbit.add_sma_km} + +> def add_sma_km( +> self, +> /, +> delta_sma_km +> ) + +Returns a copy of the state with a provided SMA added to the current one + +:type delta_sma_km: float +:rtype: Orbit + + +##### Method `add_ta_deg` {#anise.astro.Orbit.add_ta_deg} + +> def add_ta_deg( +> self, +> /, +> delta_ta_deg +> ) + +Returns a copy of the state with a provided TA added to the current one + +:type delta_ta_deg: float +:rtype: Orbit + + +##### Method `altitude_km` {#anise.astro.Orbit.altitude_km} + +> def altitude_km( +> self, +> / +> ) + +Returns the altitude in km + +:rtype: float + + +##### Method `aol_deg` {#anise.astro.Orbit.aol_deg} + +> def aol_deg( +> self, +> / +> ) + +Returns the argument of latitude in degrees + +NOTE: If the orbit is near circular, the AoL will be computed from the true longitude +instead of relying on the ill-defined true anomaly. + +:rtype: float + + +##### Method `aop_deg` {#anise.astro.Orbit.aop_deg} + +> def aop_deg( +> self, +> / +> ) + +Returns the argument of periapsis in degrees + +:rtype: float + + +##### Method `apoapsis_altitude_km` {#anise.astro.Orbit.apoapsis_altitude_km} + +> def apoapsis_altitude_km( +> self, +> / +> ) + +Returns the altitude of apoapsis (or apogee around Earth), in kilometers. + +:rtype: float + + +##### Method `apoapsis_km` {#anise.astro.Orbit.apoapsis_km} + +> def apoapsis_km( +> self, +> / +> ) + +Returns the radius of apoapsis (or apogee around Earth), in kilometers. + +:rtype: float + + +##### Method `at_epoch` {#anise.astro.Orbit.at_epoch} + +> def at_epoch( +> self, +> /, +> new_epoch +> ) + +Adjusts the true anomaly of this orbit using the mean anomaly. + +##### Astrodynamics note +This is not a true propagation of the orbit. This is akin to a two body propagation ONLY without any other force models applied. +Use Nyx for high fidelity propagation. + +:type new_epoch: Epoch +:rtype: Orbit + + +##### Method `c3_km2_s2` {#anise.astro.Orbit.c3_km2_s2} + +> def c3_km2_s2( +> self, +> / +> ) + +Returns the $C_3$ of this orbit in km^2/s^2 + +:rtype: float + + +##### Method `cartesian_pos_vel` {#anise.astro.Orbit.cartesian_pos_vel} + +> def cartesian_pos_vel( +> self, +> / +> ) + +Returns this state as a Cartesian vector of size 6 in [km, km, km, km/s, km/s, km/s] + +Note that the time is **not** returned in the vector. +:rtype: numpy.array + + +##### Method `dcm3x3_from_rcn_to_inertial` {#anise.astro.Orbit.dcm3x3_from_rcn_to_inertial} + +> def dcm3x3_from_rcn_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{r}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure + +:rtype: DCM + + +##### Method `dcm3x3_from_ric_to_inertial` {#anise.astro.Orbit.dcm3x3_from_ric_to_inertial} + +> def dcm3x3_from_ric_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame + +##### Frame warning +If the state is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Build the c vector as the normalized orbital momentum vector +2. Build the i vector as the cross product of \hat{r} and c +3. Build the RIC DCM as a 3x3 of the columns [\hat{r}, \hat{i}, \hat{c}] +4. Return the DCM structure **without** accounting for the transport theorem. + +:rtype: DCM + + +##### Method `dcm3x3_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm3x3_from_topocentric_to_body_fixed} + +> def dcm3x3_from_topocentric_to_body_fixed( +> self, +> / +> ) + +Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state. + +##### Frame warning +If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID. + +##### Source +From the GMAT MathSpec, page 30 section 2.6.9 and from Calculate\_RFT in TopocentricAxes.cpp, this returns the +rotation matrix from the topocentric frame (SEZ) to body fixed frame. +In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric +to body fixed. + +:rtype: DCM + + +##### Method `dcm3x3_from_vnc_to_inertial` {#anise.astro.Orbit.dcm3x3_from_vnc_to_inertial} + +> def dcm3x3_from_vnc_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{v}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure. + +:rtype: DCM + + +##### Method `dcm_from_rcn_to_inertial` {#anise.astro.Orbit.dcm_from_rcn_to_inertial} + +> def dcm_from_rcn_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{r}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `dcm_from_ric_to_inertial` {#anise.astro.Orbit.dcm_from_ric_to_inertial} + +> def dcm_from_ric_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame + +##### Frame warning +If the state is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute the state data one millisecond before and one millisecond assuming two body dynamics +2. Compute the DCM for this state, and the pre and post states +3. Build the c vector as the normalized orbital momentum vector +4. Build the i vector as the cross product of \hat{r} and c +5. Build the RIC DCM as a 3x3 of the columns [\hat{r}, \hat{i}, \hat{c}], for the post, post, and current states +6. Compute the difference between the DCMs of the pre and post states, to build the DCM time derivative +7. Return the DCM structure with a 6x6 state DCM. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `dcm_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm_from_topocentric_to_body_fixed} + +> def dcm_from_topocentric_to_body_fixed( +> self, +> /, +> _from +> ) + +Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state. + +##### Frame warnings ++ If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID. ++ (Usually) no time derivative can be computed: the orbit is expected to be a body fixed frame where the at\_epoch function will fail. Exceptions for Moon body fixed frames. + +##### UNUSED Arguments ++ from: ID of this new frame. Only used to set the "from" frame of the DCM. -- No longer used since 0.5.3 + +##### Source +From the GMAT MathSpec, page 30 section 2.6.9 and from Calculate\_RFT in TopocentricAxes.cpp, this returns the +rotation matrix from the topocentric frame (SEZ) to body fixed frame. +In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric +to body fixed. + +:type _from: float +:rtype: DCM + + +##### Method `dcm_from_vnc_to_inertial` {#anise.astro.Orbit.dcm_from_vnc_to_inertial} + +> def dcm_from_vnc_to_inertial( +> self, +> / +> ) + +Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross) + +##### Frame warning +If the stattion is NOT in an inertial frame, then this computation is INVALID. + +##### Algorithm +1. Compute \hat{v}, \hat{h}, the unit vectors of the radius and orbital momentum. +2. Compute the cross product of these +3. Build the DCM with these unit vectors +4. Compute the difference between the DCMs of the pre and post states (+/- 1 ms), to build the DCM time derivative +4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set. + +##### Note on the time derivative +If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set. +Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame. + +:rtype: DCM + + +##### Method `declination_deg` {#anise.astro.Orbit.declination_deg} + +> def declination_deg( +> self, +> / +> ) + +Returns the declination of this orbit in degrees + +:rtype: float + + +##### Method `distance_to_km` {#anise.astro.Orbit.distance_to_km} + +> def distance_to_km( +> self, +> /, +> other +> ) + +Returns the distance in kilometers between this state and another state, if both frame match (epoch does not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `duration_to_radius` {#anise.astro.Orbit.duration_to_radius} + +> def duration_to_radius( +> self, +> /, +> radius_km +> ) + +Calculates the duration to reach a specific radius in the orbit. + +This function computes the time it will take for the orbiting body to reach +the given radius\_km from its current position. The calculation assumes +two-body dynamics and considers the direction of motion. + +##### Assumptions & Limitations + +- Assumes pure Keplerian motion. +- For elliptical orbits, if the radius is reachable at two points (ascending and descending parts + of the orbit), this function calculates the time to reach the radius corresponding to the + true anomaly in \[0, PI] (typically the ascending part or up to apoapsis if starting past periapsis). +- For circular orbits, if the radius is within the apoapse and periapse, then a duration of zero is returned. +- For hyperbolic/parabolic orbits, the true anomaly at radius is also computed in \[0, PI]. If this + point is in the past, the function returns an error, as it doesn't look for solutions on the + departing leg if `nu > PI` would be required (unless current TA is already > PI and target radius is further along). + The current implementation strictly uses the acos result, so nu\_rad\_at\_radius is always `0 <= nu <= PI`. + This means it finds the time to reach the radius on the path from periapsis up to the point where true anomaly is PI. + +:type radius_km: float +:rtype: Duration + + +##### Method `ea_deg` {#anise.astro.Orbit.ea_deg} + +> def ea_deg( +> self, +> / +> ) + +Returns the eccentric anomaly in degrees + +This is a conversion from GMAT's StateConversionUtil::TrueToEccentricAnomaly + +:rtype: float + + +##### Method `ecc` {#anise.astro.Orbit.ecc} + +> def ecc( +> self, +> / +> ) + +Returns the eccentricity (no unit) + +:rtype: float + + +##### Method `energy_km2_s2` {#anise.astro.Orbit.energy_km2_s2} + +> def energy_km2_s2( +> self, +> / +> ) + +Returns the specific mechanical energy in km^2/s^2 + +:rtype: float + + +##### Method `eq_within` {#anise.astro.Orbit.eq_within} + +> def eq_within( +> self, +> /, +> other, +> radial_tol_km, +> velocity_tol_km_s +> ) + +Returns whether this orbit and another are equal within the specified radial and velocity absolute tolerances + +:type other: Orbit +:type radial_tol_km: float +:type velocity_tol_km_s: float +:rtype: bool + + +##### Method `fpa_deg` {#anise.astro.Orbit.fpa_deg} + +> def fpa_deg( +> self, +> / +> ) + +Returns the flight path angle in degrees + +:rtype: float + + +##### Method `from_cartesian` {#anise.astro.Orbit.from_cartesian} + +> def from_cartesian( +> x_km, +> y_km, +> z_km, +> vx_km_s, +> vy_km_s, +> vz_km_s, +> epoch, +> frame +> ) + +Creates a new Cartesian state in the provided frame at the provided Epoch. + +**Units:** km, km, km, km/s, km/s, km/s + +:type x_km: float +:type y_km: float +:type z_km: float +:type vx_km_s: float +:type vy_km_s: float +:type vz_km_s: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian` {#anise.astro.Orbit.from_keplerian} + +> def from_keplerian( +> sma_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit around the provided Celestial or Geoid frame from the Keplerian orbital elements. + +**Units:** km, none, degrees, degrees, degrees, degrees + +NOTE: The state is defined in Cartesian coordinates as they are non-singular. This causes rounding +errors when creating a state from its Keplerian orbital elements (cf. the state tests). +One should expect these errors to be on the order of 1e-12. + +:type sma_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_altitude` {#anise.astro.Orbit.from_keplerian_altitude} + +> def from_keplerian_altitude( +> sma_altitude_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit from the provided semi-major axis altitude in kilometers + +:type sma_altitude_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_apsis_altitude` {#anise.astro.Orbit.from_keplerian_apsis_altitude} + +> def from_keplerian_apsis_altitude( +> apo_alt_km, +> peri_alt_km, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Creates a new Orbit from the provided altitudes of apoapsis and periapsis, in kilometers + +:type apo_alt_km: float +:type peri_alt_km: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_apsis_radii` {#anise.astro.Orbit.from_keplerian_apsis_radii} + +> def from_keplerian_apsis_radii( +> r_a_km, +> r_p_km, +> inc_deg, +> raan_deg, +> aop_deg, +> ta_deg, +> epoch, +> frame +> ) + +Attempts to create a new Orbit from the provided radii of apoapsis and periapsis, in kilometers + +:type r_a_km: float +:type r_p_km: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ta_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_keplerian_mean_anomaly` {#anise.astro.Orbit.from_keplerian_mean_anomaly} + +> def from_keplerian_mean_anomaly( +> sma_km, +> ecc, +> inc_deg, +> raan_deg, +> aop_deg, +> ma_deg, +> epoch, +> frame +> ) + +Initializes a new orbit from the Keplerian orbital elements using the mean anomaly instead of the true anomaly. + +##### Implementation notes +This function starts by converting the mean anomaly to true anomaly, and then it initializes the orbit +using the keplerian(..) method. +The conversion is from GMAT's MeanToTrueAnomaly function, transliterated originally by Claude and GPT4 with human adjustments. + +:type sma_km: float +:type ecc: float +:type inc_deg: float +:type raan_deg: float +:type aop_deg: float +:type ma_deg: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `from_latlongalt` {#anise.astro.Orbit.from_latlongalt} + +> def from_latlongalt( +> latitude_deg, +> longitude_deg, +> height_km, +> angular_velocity, +> epoch, +> frame +> ) + +Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid given the angular velocity. + +**Units:** degrees, degrees, km, rad/s +NOTE: This computation differs from the spherical coordinates because we consider the flattening of body. +Reference: G. Xu and Y. Xu, "GPS", DOI 10.1007/978-3-662-50367-6_2, 2016 + +:type latitude_deg: float +:type longitude_deg: float +:type height_km: float +:type angular_velocity: float +:type epoch: Epoch +:type frame: Frame +:rtype: Orbit + + +##### Method `height_km` {#anise.astro.Orbit.height_km} + +> def height_km( +> self, +> / +> ) + +Returns the geodetic height in km. + +Reference: Vallado, 4th Ed., Algorithm 12 page 172. + +:rtype: float + + +##### Method `hmag` {#anise.astro.Orbit.hmag} + +> def hmag( +> self, +> / +> ) + +Returns the norm of the orbital momentum + +:rtype: float + + +##### Method `hx` {#anise.astro.Orbit.hx} + +> def hx( +> self, +> / +> ) + +Returns the orbital momentum value on the X axis + +:rtype: float + + +##### Method `hy` {#anise.astro.Orbit.hy} + +> def hy( +> self, +> / +> ) + +Returns the orbital momentum value on the Y axis + +:rtype: float + + +##### Method `hyperbolic_anomaly_deg` {#anise.astro.Orbit.hyperbolic_anomaly_deg} + +> def hyperbolic_anomaly_deg( +> self, +> / +> ) + +Returns the hyperbolic anomaly in degrees between 0 and 360.0 +Returns an error if the orbit is not hyperbolic. + +:rtype: float + + +##### Method `hz` {#anise.astro.Orbit.hz} + +> def hz( +> self, +> / +> ) + +Returns the orbital momentum value on the Z axis + +:rtype: float + + +##### Method `inc_deg` {#anise.astro.Orbit.inc_deg} + +> def inc_deg( +> self, +> / +> ) + +Returns the inclination in degrees + +:rtype: float + + +##### Method `is_brouwer_short_valid` {#anise.astro.Orbit.is_brouwer_short_valid} + +> def is_brouwer_short_valid( +> self, +> / +> ) + +Returns whether this state satisfies the requirement to compute the Mean Brouwer Short orbital +element set. + +This is a conversion from GMAT's StateConversionUtil::CartesianToBrouwerMeanShort. +The details are at the log level info. +NOTE: Mean Brouwer Short are only defined around Earth. However, nyx does *not* check the +main celestial body around which the state is defined (GMAT does perform this verification). + +:rtype: bool + + +##### Method `latitude_deg` {#anise.astro.Orbit.latitude_deg} + +> def latitude_deg( +> self, +> / +> ) + +Returns the geodetic latitude (φ) in degrees. Value is between -180 and +180 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `latlongalt` {#anise.astro.Orbit.latlongalt} + +> def latlongalt( +> self, +> / +> ) + +Returns the geodetic latitude, geodetic longitude, and geodetic height, respectively in degrees, degrees, and kilometers. + +##### Algorithm +This uses the Heikkinen procedure, which is not iterative. The results match Vallado and GMAT. + +:rtype: typing.Tuple + + +##### Method `light_time` {#anise.astro.Orbit.light_time} + +> def light_time( +> self, +> / +> ) + +Returns the light time duration between this object and the origin of its reference frame. + +:rtype: Duration + + +##### Method `longitude_360_deg` {#anise.astro.Orbit.longitude_360_deg} + +> def longitude_360_deg( +> self, +> / +> ) + +Returns the geodetic longitude (λ) in degrees. Value is between 0 and 360 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `longitude_deg` {#anise.astro.Orbit.longitude_deg} + +> def longitude_deg( +> self, +> / +> ) + +Returns the geodetic longitude (λ) in degrees. Value is between -180 and 180 degrees. + +##### Frame warning +This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**. + +:rtype: float + + +##### Method `ltan_deg` {#anise.astro.Orbit.ltan_deg} + +> def ltan_deg( +> self, +> / +> ) + +Returns the Longitude of the Ascending Node (LTAN), or an error of equatorial orbits + +:rtype: float + + +##### Method `ma_deg` {#anise.astro.Orbit.ma_deg} + +> def ma_deg( +> self, +> / +> ) + +Returns the mean anomaly in degrees + +This is a conversion from GMAT's StateConversionUtil::TrueToMeanAnomaly + +:rtype: float + + +##### Method `mean_motion_deg_s` {#anise.astro.Orbit.mean_motion_deg_s} + +> def mean_motion_deg_s( +> self, +> / +> ) + +Returns the mean motion in degrees per seconds + +:rtype: float + + +##### Method `periapsis_altitude_km` {#anise.astro.Orbit.periapsis_altitude_km} + +> def periapsis_altitude_km( +> self, +> / +> ) + +Returns the altitude of periapsis (or perigee around Earth), in kilometers. + +:rtype: float + + +##### Method `periapsis_km` {#anise.astro.Orbit.periapsis_km} + +> def periapsis_km( +> self, +> / +> ) + +Returns the radius of periapsis (or perigee around Earth), in kilometers. + +:rtype: float + + +##### Method `period` {#anise.astro.Orbit.period} + +> def period( +> self, +> / +> ) + +Returns the period in seconds + +:rtype: Duration + + +##### Method `raan_deg` {#anise.astro.Orbit.raan_deg} + +> def raan_deg( +> self, +> / +> ) + +Returns the right ascension of the ascending node in degrees + +:rtype: float + + +##### Method `rel_difference` {#anise.astro.Orbit.rel_difference} + +> def rel_difference( +> self, +> /, +> other +> ) + +Returns the relative difference between this orbit and another for the position and velocity, respectively the first and second return values. +Both return values are UNITLESS because the relative difference is computed as the absolute difference divided by the rmag and vmag of this object. +Raises an error if the frames do not match, if the position is zero or the velocity is zero. + +:type other: Orbit +:rtype: typing.Tuple + + +##### Method `rel_pos_diff` {#anise.astro.Orbit.rel_pos_diff} + +> def rel_pos_diff( +> self, +> /, +> other +> ) + +Returns the relative position difference (unitless) between this orbit and another. +This is computed by dividing the absolute difference by the norm of this object's radius vector. +If the radius is zero, this function raises a math error. +Raises an error if the frames do not match or (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `rel_vel_diff` {#anise.astro.Orbit.rel_vel_diff} + +> def rel_vel_diff( +> self, +> /, +> other +> ) + +Returns the absolute velocity difference in kilometer per second between this orbit and another. +Raises an error if the frames do not match (epochs do not need to match). + +:type other: Orbit +:rtype: float + + +##### Method `ric_difference` {#anise.astro.Orbit.ric_difference} + +> def ric_difference( +> self, +> /, +> other +> ) + +Returns a Cartesian state representing the RIC difference between self and other, in position and velocity (with transport theorem). +Refer to dcm_from_ric_to_inertial for details on the RIC frame. + +##### Algorithm +1. Compute the RIC DCM of self +2. Rotate self into the RIC frame +3. Rotation other into the RIC frame +4. Compute the difference between these two states +5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState + +:type other: Orbit +:rtype: Orbit + + +##### Method `right_ascension_deg` {#anise.astro.Orbit.right_ascension_deg} + +> def right_ascension_deg( +> self, +> / +> ) + +Returns the right ascension of this orbit in degrees + +:rtype: float + + +##### Method `rmag_km` {#anise.astro.Orbit.rmag_km} + +> def rmag_km( +> self, +> / +> ) + +Returns the magnitude of the radius vector in km + +:rtype: float + + +##### Method `rms_radius_km` {#anise.astro.Orbit.rms_radius_km} + +> def rms_radius_km( +> self, +> /, +> other +> ) + +Returns the root sum squared (RMS) radius difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rms_velocity_km_s` {#anise.astro.Orbit.rms_velocity_km_s} + +> def rms_velocity_km_s( +> self, +> /, +> other +> ) + +Returns the root sum squared (RMS) velocity difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rss_radius_km` {#anise.astro.Orbit.rss_radius_km} + +> def rss_radius_km( +> self, +> /, +> other +> ) + +Returns the root mean squared (RSS) radius difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `rss_velocity_km_s` {#anise.astro.Orbit.rss_velocity_km_s} + +> def rss_velocity_km_s( +> self, +> /, +> other +> ) + +Returns the root mean squared (RSS) velocity difference between this state and another state, if both frames match (epoch does not need to match) + +:type other: Orbit +:rtype: float + + +##### Method `semi_minor_axis_km` {#anise.astro.Orbit.semi_minor_axis_km} + +> def semi_minor_axis_km( +> self, +> / +> ) + +Returns the semi minor axis in km, includes code for a hyperbolic orbit + +:rtype: float + + +##### Method `semi_parameter_km` {#anise.astro.Orbit.semi_parameter_km} + +> def semi_parameter_km( +> self, +> / +> ) + +Returns the semi parameter (or semilatus rectum) + +:rtype: float + + +##### Method `set_aop_deg` {#anise.astro.Orbit.set_aop_deg} + +> def set_aop_deg( +> self, +> /, +> new_aop_deg +> ) + +Mutates this orbit to change the AOP + +:type new_aop_deg: float +:rtype: None + + +##### Method `set_ecc` {#anise.astro.Orbit.set_ecc} + +> def set_ecc( +> self, +> /, +> new_ecc +> ) + +Mutates this orbit to change the ECC + +:type new_ecc: float +:rtype: None + + +##### Method `set_inc_deg` {#anise.astro.Orbit.set_inc_deg} + +> def set_inc_deg( +> self, +> /, +> new_inc_deg +> ) + +Mutates this orbit to change the INC + +:type new_inc_deg: float +:rtype: None + + +##### Method `set_raan_deg` {#anise.astro.Orbit.set_raan_deg} + +> def set_raan_deg( +> self, +> /, +> new_raan_deg +> ) + +Mutates this orbit to change the RAAN + +:type new_raan_deg: float +:rtype: None + + +##### Method `set_sma_km` {#anise.astro.Orbit.set_sma_km} + +> def set_sma_km( +> self, +> /, +> new_sma_km +> ) + +Mutates this orbit to change the SMA + +:type new_sma_km: float +:rtype: None + + +##### Method `set_ta_deg` {#anise.astro.Orbit.set_ta_deg} + +> def set_ta_deg( +> self, +> /, +> new_ta_deg +> ) + +Mutates this orbit to change the TA + +:type new_ta_deg: float +:rtype: None + + +##### Method `sma_altitude_km` {#anise.astro.Orbit.sma_altitude_km} + +> def sma_altitude_km( +> self, +> / +> ) + +Returns the SMA altitude in km + +:rtype: float + + +##### Method `sma_km` {#anise.astro.Orbit.sma_km} + +> def sma_km( +> self, +> / +> ) + +Returns the semi-major axis in km + +:rtype: float + + +##### Method `ta_deg` {#anise.astro.Orbit.ta_deg} + +> def ta_deg( +> self, +> / +> ) + +Returns the true anomaly in degrees between 0 and 360.0 + +NOTE: This function will emit a warning stating that the TA should be avoided if in a very near circular orbit +Code from + +LIMITATION: For an orbit whose true anomaly is (very nearly) 0.0 or 180.0, this function may return either 0.0 or 180.0 with a very small time increment. +This is due to the precision of the cosine calculation: if the arccosine calculation is out of bounds, the sign of the cosine of the true anomaly is used +to determine whether the true anomaly should be 0.0 or 180.0. **In other words**, there is an ambiguity in the computation in the true anomaly exactly at 180.0 and 0.0. + +:rtype: float + + +##### Method `ta_dot_deg_s` {#anise.astro.Orbit.ta_dot_deg_s} + +> def ta_dot_deg_s( +> self, +> / +> ) + +Returns the time derivative of the true anomaly computed as the 360.0 degrees divided by the orbital period (in seconds). + +:rtype: float + + +##### Method `tlong_deg` {#anise.astro.Orbit.tlong_deg} + +> def tlong_deg( +> self, +> / +> ) + +Returns the true longitude in degrees + +:rtype: float + + +##### Method `velocity_declination_deg` {#anise.astro.Orbit.velocity_declination_deg} + +> def velocity_declination_deg( +> self, +> / +> ) + +Returns the velocity declination of this orbit in degrees + +:rtype: float + + +##### Method `vinf_periapsis_km` {#anise.astro.Orbit.vinf_periapsis_km} + +> def vinf_periapsis_km( +> self, +> /, +> turn_angle_degrees +> ) + +Returns the radius of periapse in kilometers for the provided turn angle of this hyperbolic orbit. +Returns an error if the orbit is not hyperbolic. + +:type turn_angle_degrees: float +:rtype: float + + +##### Method `vinf_turn_angle_deg` {#anise.astro.Orbit.vinf_turn_angle_deg} + +> def vinf_turn_angle_deg( +> self, +> /, +> periapsis_km +> ) + +Returns the turn angle in degrees for the provided radius of periapse passage of this hyperbolic orbit +Returns an error if the orbit is not hyperbolic. + +:type periapsis_km: float +:rtype: float + + +##### Method `vmag_km_s` {#anise.astro.Orbit.vmag_km_s} + +> def vmag_km_s( +> self, +> / +> ) + +Returns the magnitude of the velocity vector in km/s + +:rtype: float + + +##### Method `vnc_difference` {#anise.astro.Orbit.vnc_difference} + +> def vnc_difference( +> self, +> /, +> other +> ) + +Returns a Cartesian state representing the VNC difference between self and other, in position and velocity (with transport theorem). +Refer to dcm_from_vnc_to_inertial for details on the VNC frame. + +##### Algorithm +1. Compute the VNC DCM of self +2. Rotate self into the VNC frame +3. Rotation other into the VNC frame +4. Compute the difference between these two states +5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState + +:type other: Orbit +:rtype: Orbit + + +##### Method `with_aop_deg` {#anise.astro.Orbit.with_aop_deg} + +> def with_aop_deg( +> self, +> /, +> new_aop_deg +> ) + +Returns a copy of the state with a new AOP + +:type new_aop_deg: float +:rtype: Orbit + + +##### Method `with_apoapsis_periapsis_km` {#anise.astro.Orbit.with_apoapsis_periapsis_km} + +> def with_apoapsis_periapsis_km( +> self, +> /, +> new_ra_km, +> new_rp_km +> ) + +Returns a copy of this state with the provided apoasis and periapsis + +:type new_ra_km: float +:type new_rp_km: float +:rtype: Orbit + + +##### Method `with_ecc` {#anise.astro.Orbit.with_ecc} + +> def with_ecc( +> self, +> /, +> new_ecc +> ) + +Returns a copy of the state with a new ECC + +:type new_ecc: float +:rtype: Orbit + + +##### Method `with_inc_deg` {#anise.astro.Orbit.with_inc_deg} + +> def with_inc_deg( +> self, +> /, +> new_inc_deg +> ) + +Returns a copy of the state with a new INC + +:type new_inc_deg: float +:rtype: Orbit + + +##### Method `with_raan_deg` {#anise.astro.Orbit.with_raan_deg} + +> def with_raan_deg( +> self, +> /, +> new_raan_deg +> ) + +Returns a copy of the state with a new RAAN + +:type new_raan_deg: float +:rtype: Orbit + + +##### Method `with_sma_km` {#anise.astro.Orbit.with_sma_km} + +> def with_sma_km( +> self, +> /, +> new_sma_km +> ) + +Returns a copy of the state with a new SMA + +:type new_sma_km: float +:rtype: Orbit + + +##### Method `with_ta_deg` {#anise.astro.Orbit.with_ta_deg} + +> def with_ta_deg( +> self, +> /, +> new_ta_deg +> ) + +Returns a copy of the state with a new TA + +:type new_ta_deg: float +:rtype: Orbit + + +# Module `anise.astro.constants` {#anise.astro.constants} + + +## Classes + + +### Class `CelestialObjects` {#anise.astro.constants.CelestialObjects} + +> class CelestialObjects( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH` {#anise.astro.constants.CelestialObjects.EARTH} + + +##### Variable `EARTH_MOON_BARYCENTER` {#anise.astro.constants.CelestialObjects.EARTH_MOON_BARYCENTER} + + +##### Variable `JUPITER` {#anise.astro.constants.CelestialObjects.JUPITER} + + +##### Variable `JUPITER_BARYCENTER` {#anise.astro.constants.CelestialObjects.JUPITER_BARYCENTER} + + +##### Variable `MARS` {#anise.astro.constants.CelestialObjects.MARS} + + +##### Variable `MARS_BARYCENTER` {#anise.astro.constants.CelestialObjects.MARS_BARYCENTER} + + +##### Variable `MERCURY` {#anise.astro.constants.CelestialObjects.MERCURY} + + +##### Variable `MOON` {#anise.astro.constants.CelestialObjects.MOON} + + +##### Variable `NEPTUNE` {#anise.astro.constants.CelestialObjects.NEPTUNE} + + +##### Variable `NEPTUNE_BARYCENTER` {#anise.astro.constants.CelestialObjects.NEPTUNE_BARYCENTER} + + +##### Variable `PLUTO_BARYCENTER` {#anise.astro.constants.CelestialObjects.PLUTO_BARYCENTER} + + +##### Variable `SATURN` {#anise.astro.constants.CelestialObjects.SATURN} + + +##### Variable `SATURN_BARYCENTER` {#anise.astro.constants.CelestialObjects.SATURN_BARYCENTER} + + +##### Variable `SOLAR_SYSTEM_BARYCENTER` {#anise.astro.constants.CelestialObjects.SOLAR_SYSTEM_BARYCENTER} + + +##### Variable `SUN` {#anise.astro.constants.CelestialObjects.SUN} + + +##### Variable `URANUS` {#anise.astro.constants.CelestialObjects.URANUS} + + +##### Variable `URANUS_BARYCENTER` {#anise.astro.constants.CelestialObjects.URANUS_BARYCENTER} + + +##### Variable `VENUS` {#anise.astro.constants.CelestialObjects.VENUS} + + +### Class `Frames` {#anise.astro.constants.Frames} + +> class Frames( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH_ECLIPJ2000` {#anise.astro.constants.Frames.EARTH_ECLIPJ2000} + + +##### Variable `EARTH_ITRF93` {#anise.astro.constants.Frames.EARTH_ITRF93} + + +##### Variable `EARTH_J2000` {#anise.astro.constants.Frames.EARTH_J2000} + + +##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.astro.constants.Frames.EARTH_MOON_BARYCENTER_J2000} + + +##### Variable `EME2000` {#anise.astro.constants.Frames.EME2000} + + +##### Variable `IAU_EARTH_FRAME` {#anise.astro.constants.Frames.IAU_EARTH_FRAME} + + +##### Variable `IAU_JUPITER_FRAME` {#anise.astro.constants.Frames.IAU_JUPITER_FRAME} + + +##### Variable `IAU_MARS_FRAME` {#anise.astro.constants.Frames.IAU_MARS_FRAME} + + +##### Variable `IAU_MERCURY_FRAME` {#anise.astro.constants.Frames.IAU_MERCURY_FRAME} + + +##### Variable `IAU_MOON_FRAME` {#anise.astro.constants.Frames.IAU_MOON_FRAME} + + +##### Variable `IAU_NEPTUNE_FRAME` {#anise.astro.constants.Frames.IAU_NEPTUNE_FRAME} + + +##### Variable `IAU_SATURN_FRAME` {#anise.astro.constants.Frames.IAU_SATURN_FRAME} + + +##### Variable `IAU_URANUS_FRAME` {#anise.astro.constants.Frames.IAU_URANUS_FRAME} + + +##### Variable `IAU_VENUS_FRAME` {#anise.astro.constants.Frames.IAU_VENUS_FRAME} + + +##### Variable `JUPITER_BARYCENTER_J2000` {#anise.astro.constants.Frames.JUPITER_BARYCENTER_J2000} + + +##### Variable `MARS_BARYCENTER_J2000` {#anise.astro.constants.Frames.MARS_BARYCENTER_J2000} + + +##### Variable `MERCURY_J2000` {#anise.astro.constants.Frames.MERCURY_J2000} + + +##### Variable `MOON_J2000` {#anise.astro.constants.Frames.MOON_J2000} + + +##### Variable `MOON_ME_DE421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE421_FRAME} + + +##### Variable `MOON_ME_DE440_ME421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE440_ME421_FRAME} + + +##### Variable `MOON_ME_FRAME` {#anise.astro.constants.Frames.MOON_ME_FRAME} + + +##### Variable `MOON_PA_DE421_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE421_FRAME} + + +##### Variable `MOON_PA_DE440_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE440_FRAME} + + +##### Variable `MOON_PA_FRAME` {#anise.astro.constants.Frames.MOON_PA_FRAME} + + +##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.astro.constants.Frames.NEPTUNE_BARYCENTER_J2000} + + +##### Variable `PLUTO_BARYCENTER_J2000` {#anise.astro.constants.Frames.PLUTO_BARYCENTER_J2000} + + +##### Variable `SATURN_BARYCENTER_J2000` {#anise.astro.constants.Frames.SATURN_BARYCENTER_J2000} + + +##### Variable `SSB_J2000` {#anise.astro.constants.Frames.SSB_J2000} + + +##### Variable `SUN_J2000` {#anise.astro.constants.Frames.SUN_J2000} + + +##### Variable `URANUS_BARYCENTER_J2000` {#anise.astro.constants.Frames.URANUS_BARYCENTER_J2000} + + +##### Variable `VENUS_J2000` {#anise.astro.constants.Frames.VENUS_J2000} + + +### Class `Orientations` {#anise.astro.constants.Orientations} + +> class Orientations( +> ... +> ) + + +#### Class variables + + +##### Variable `ECLIPJ2000` {#anise.astro.constants.Orientations.ECLIPJ2000} + + +##### Variable `IAU_EARTH` {#anise.astro.constants.Orientations.IAU_EARTH} + + +##### Variable `IAU_JUPITER` {#anise.astro.constants.Orientations.IAU_JUPITER} + + +##### Variable `IAU_MARS` {#anise.astro.constants.Orientations.IAU_MARS} + + +##### Variable `IAU_MERCURY` {#anise.astro.constants.Orientations.IAU_MERCURY} + + +##### Variable `IAU_MOON` {#anise.astro.constants.Orientations.IAU_MOON} + + +##### Variable `IAU_NEPTUNE` {#anise.astro.constants.Orientations.IAU_NEPTUNE} + + +##### Variable `IAU_SATURN` {#anise.astro.constants.Orientations.IAU_SATURN} + + +##### Variable `IAU_URANUS` {#anise.astro.constants.Orientations.IAU_URANUS} + + +##### Variable `IAU_VENUS` {#anise.astro.constants.Orientations.IAU_VENUS} + + +##### Variable `ITRF93` {#anise.astro.constants.Orientations.ITRF93} + + +##### Variable `J2000` {#anise.astro.constants.Orientations.J2000} + + +##### Variable `MOON_ME` {#anise.astro.constants.Orientations.MOON_ME} + + +##### Variable `MOON_ME_DE421` {#anise.astro.constants.Orientations.MOON_ME_DE421} + + +##### Variable `MOON_ME_DE440_ME421` {#anise.astro.constants.Orientations.MOON_ME_DE440_ME421} + + +##### Variable `MOON_PA` {#anise.astro.constants.Orientations.MOON_PA} + + +##### Variable `MOON_PA_DE421` {#anise.astro.constants.Orientations.MOON_PA_DE421} + + +##### Variable `MOON_PA_DE440` {#anise.astro.constants.Orientations.MOON_PA_DE440} + + +### Class `UsualConstants` {#anise.astro.constants.UsualConstants} + +> class UsualConstants( +> ... +> ) + + +#### Class variables + + +##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_EARTH_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_MOON_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `SPEED_OF_LIGHT_KM_S` {#anise.astro.constants.UsualConstants.SPEED_OF_LIGHT_KM_S} + + +# Module `anise.constants` {#anise.constants} + + +## Classes + + +### Class `CelestialObjects` {#anise.constants.CelestialObjects} + +> class CelestialObjects( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH` {#anise.constants.CelestialObjects.EARTH} + + +##### Variable `EARTH_MOON_BARYCENTER` {#anise.constants.CelestialObjects.EARTH_MOON_BARYCENTER} + + +##### Variable `JUPITER` {#anise.constants.CelestialObjects.JUPITER} + + +##### Variable `JUPITER_BARYCENTER` {#anise.constants.CelestialObjects.JUPITER_BARYCENTER} + + +##### Variable `MARS` {#anise.constants.CelestialObjects.MARS} + + +##### Variable `MARS_BARYCENTER` {#anise.constants.CelestialObjects.MARS_BARYCENTER} + + +##### Variable `MERCURY` {#anise.constants.CelestialObjects.MERCURY} + + +##### Variable `MOON` {#anise.constants.CelestialObjects.MOON} + + +##### Variable `NEPTUNE` {#anise.constants.CelestialObjects.NEPTUNE} + + +##### Variable `NEPTUNE_BARYCENTER` {#anise.constants.CelestialObjects.NEPTUNE_BARYCENTER} + + +##### Variable `PLUTO_BARYCENTER` {#anise.constants.CelestialObjects.PLUTO_BARYCENTER} + + +##### Variable `SATURN` {#anise.constants.CelestialObjects.SATURN} + + +##### Variable `SATURN_BARYCENTER` {#anise.constants.CelestialObjects.SATURN_BARYCENTER} + + +##### Variable `SOLAR_SYSTEM_BARYCENTER` {#anise.constants.CelestialObjects.SOLAR_SYSTEM_BARYCENTER} + + +##### Variable `SUN` {#anise.constants.CelestialObjects.SUN} + + +##### Variable `URANUS` {#anise.constants.CelestialObjects.URANUS} + + +##### Variable `URANUS_BARYCENTER` {#anise.constants.CelestialObjects.URANUS_BARYCENTER} + + +##### Variable `VENUS` {#anise.constants.CelestialObjects.VENUS} + + +### Class `Frames` {#anise.constants.Frames} + +> class Frames( +> ... +> ) + + +#### Class variables + + +##### Variable `EARTH_ECLIPJ2000` {#anise.constants.Frames.EARTH_ECLIPJ2000} + + +##### Variable `EARTH_ITRF93` {#anise.constants.Frames.EARTH_ITRF93} + + +##### Variable `EARTH_J2000` {#anise.constants.Frames.EARTH_J2000} + + +##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.constants.Frames.EARTH_MOON_BARYCENTER_J2000} + + +##### Variable `EME2000` {#anise.constants.Frames.EME2000} + + +##### Variable `IAU_EARTH_FRAME` {#anise.constants.Frames.IAU_EARTH_FRAME} + + +##### Variable `IAU_JUPITER_FRAME` {#anise.constants.Frames.IAU_JUPITER_FRAME} + + +##### Variable `IAU_MARS_FRAME` {#anise.constants.Frames.IAU_MARS_FRAME} + + +##### Variable `IAU_MERCURY_FRAME` {#anise.constants.Frames.IAU_MERCURY_FRAME} + + +##### Variable `IAU_MOON_FRAME` {#anise.constants.Frames.IAU_MOON_FRAME} + + +##### Variable `IAU_NEPTUNE_FRAME` {#anise.constants.Frames.IAU_NEPTUNE_FRAME} + + +##### Variable `IAU_SATURN_FRAME` {#anise.constants.Frames.IAU_SATURN_FRAME} + + +##### Variable `IAU_URANUS_FRAME` {#anise.constants.Frames.IAU_URANUS_FRAME} + + +##### Variable `IAU_VENUS_FRAME` {#anise.constants.Frames.IAU_VENUS_FRAME} + + +##### Variable `JUPITER_BARYCENTER_J2000` {#anise.constants.Frames.JUPITER_BARYCENTER_J2000} + + +##### Variable `MARS_BARYCENTER_J2000` {#anise.constants.Frames.MARS_BARYCENTER_J2000} + + +##### Variable `MERCURY_J2000` {#anise.constants.Frames.MERCURY_J2000} + + +##### Variable `MOON_J2000` {#anise.constants.Frames.MOON_J2000} + + +##### Variable `MOON_ME_DE421_FRAME` {#anise.constants.Frames.MOON_ME_DE421_FRAME} + + +##### Variable `MOON_ME_DE440_ME421_FRAME` {#anise.constants.Frames.MOON_ME_DE440_ME421_FRAME} + + +##### Variable `MOON_ME_FRAME` {#anise.constants.Frames.MOON_ME_FRAME} + + +##### Variable `MOON_PA_DE421_FRAME` {#anise.constants.Frames.MOON_PA_DE421_FRAME} + + +##### Variable `MOON_PA_DE440_FRAME` {#anise.constants.Frames.MOON_PA_DE440_FRAME} + + +##### Variable `MOON_PA_FRAME` {#anise.constants.Frames.MOON_PA_FRAME} + + +##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.constants.Frames.NEPTUNE_BARYCENTER_J2000} + + +##### Variable `PLUTO_BARYCENTER_J2000` {#anise.constants.Frames.PLUTO_BARYCENTER_J2000} + + +##### Variable `SATURN_BARYCENTER_J2000` {#anise.constants.Frames.SATURN_BARYCENTER_J2000} + + +##### Variable `SSB_J2000` {#anise.constants.Frames.SSB_J2000} + + +##### Variable `SUN_J2000` {#anise.constants.Frames.SUN_J2000} + + +##### Variable `URANUS_BARYCENTER_J2000` {#anise.constants.Frames.URANUS_BARYCENTER_J2000} + + +##### Variable `VENUS_J2000` {#anise.constants.Frames.VENUS_J2000} + + +### Class `Orientations` {#anise.constants.Orientations} + +> class Orientations( +> ... +> ) + + +#### Class variables + + +##### Variable `ECLIPJ2000` {#anise.constants.Orientations.ECLIPJ2000} + + +##### Variable `IAU_EARTH` {#anise.constants.Orientations.IAU_EARTH} + + +##### Variable `IAU_JUPITER` {#anise.constants.Orientations.IAU_JUPITER} + + +##### Variable `IAU_MARS` {#anise.constants.Orientations.IAU_MARS} + + +##### Variable `IAU_MERCURY` {#anise.constants.Orientations.IAU_MERCURY} + + +##### Variable `IAU_MOON` {#anise.constants.Orientations.IAU_MOON} + + +##### Variable `IAU_NEPTUNE` {#anise.constants.Orientations.IAU_NEPTUNE} + + +##### Variable `IAU_SATURN` {#anise.constants.Orientations.IAU_SATURN} + + +##### Variable `IAU_URANUS` {#anise.constants.Orientations.IAU_URANUS} + + +##### Variable `IAU_VENUS` {#anise.constants.Orientations.IAU_VENUS} + + +##### Variable `ITRF93` {#anise.constants.Orientations.ITRF93} + + +##### Variable `J2000` {#anise.constants.Orientations.J2000} + + +##### Variable `MOON_ME` {#anise.constants.Orientations.MOON_ME} + + +##### Variable `MOON_ME_DE421` {#anise.constants.Orientations.MOON_ME_DE421} + + +##### Variable `MOON_ME_DE440_ME421` {#anise.constants.Orientations.MOON_ME_DE440_ME421} + + +##### Variable `MOON_PA` {#anise.constants.Orientations.MOON_PA} + + +##### Variable `MOON_PA_DE421` {#anise.constants.Orientations.MOON_PA_DE421} + + +##### Variable `MOON_PA_DE440` {#anise.constants.Orientations.MOON_PA_DE440} + + +### Class `UsualConstants` {#anise.constants.UsualConstants} + +> class UsualConstants( +> ... +> ) + + +#### Class variables + + +##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S` {#anise.constants.UsualConstants.MEAN_EARTH_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S` {#anise.constants.UsualConstants.MEAN_MOON_ANGULAR_VELOCITY_DEG_S} + + +##### Variable `SPEED_OF_LIGHT_KM_S` {#anise.constants.UsualConstants.SPEED_OF_LIGHT_KM_S} + + +# Module `anise.rotation` {#anise.rotation} + + +## Classes + + +### Class `DCM` {#anise.rotation.DCM} + +> class DCM( +> np_rot_mat, +> from_id, +> to_id, +> np_rot_mat_dt=None +> ) + +Defines a direction cosine matrix from one frame ID to another frame ID, optionally with its time derivative. +It provides a number of run-time checks that prevent invalid rotations. + +:type np_rot_mat: numpy.array +:type from_id: int +:type to_id: int +:type np_rot_mat_dt: numpy.array, optional +:rtype: DCM + + +#### Instance variables + + +##### Variable `from_id` {#anise.rotation.DCM.from_id} + +:rtype: int + + +##### Variable `rot_mat` {#anise.rotation.DCM.rot_mat} + +:rtype: numpy.array + + +##### Variable `rot_mat_dt` {#anise.rotation.DCM.rot_mat_dt} + +:rtype: numpy.array + + +##### Variable `to_id` {#anise.rotation.DCM.to_id} + +:rtype: int + + +#### Methods + + +##### Method `from_identity` {#anise.rotation.DCM.from_identity} + +> def from_identity( +> from_id, +> to_id +> ) + +Builds an identity rotation. + +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r1` {#anise.rotation.DCM.from_r1} + +> def from_r1( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the X axis. + +Source: euler1 function from Baslisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r2` {#anise.rotation.DCM.from_r2} + +> def from_r2( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the Y axis. + +Source: euler2 function from Basilisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r3` {#anise.rotation.DCM.from_r3} + +> def from_r3( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the Z axis. + +Source: euler3 function from Basilisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `get_state_dcm` {#anise.rotation.DCM.get_state_dcm} + +> def get_state_dcm( +> self, +> / +> ) + +Returns the 6x6 DCM to rotate a state. If the time derivative of this DCM is defined, this 6x6 accounts for the transport theorem. +Warning: you MUST manually install numpy to call this function. +:rtype: numpy.array + + +##### Method `is_identity` {#anise.rotation.DCM.is_identity} + +> def is_identity( +> self, +> / +> ) + +Returns whether this rotation is identity, checking first the frames and then the rotation matrix (but ignores its time derivative) + +:rtype: bool + + +##### Method `is_valid` {#anise.rotation.DCM.is_valid} + +> def is_valid( +> self, +> /, +> unit_tol, +> det_tol +> ) + +Returns whether the rot\_mat of this DCM is a valid rotation matrix. +The criteria for validity are: +-- The columns of the matrix are unit vectors, within a specified tolerance (unit_tol). +-- The determinant of the matrix formed by unitizing the columns of the input matrix is 1, within a specified tolerance. This criterion ensures that the columns of the matrix are nearly orthogonal, and that they form a right-handed basis (det_tol). +[Source: SPICE's rotation.req](https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/rotation.html#Validating%20a%20rotation%20matrix) + +:type unit_tol: float +:type det_tol: float +:rtype: bool + + +##### Method `transpose` {#anise.rotation.DCM.transpose} + +> def transpose( +> self, +> / +> ) + +Returns the transpose of this DCM + +:rtype: DCM + + +# Module `anise.time` {#anise.time} + + +## Classes + + +### Class `Duration` {#anise.time.Duration} + +> class Duration( +> string_repr +> ) + +Defines generally usable durations for nanosecond precision valid for 32,768 centuries in either direction, and only on 80 bits / 10 octets. + +**Important conventions:** +1. The negative durations can be mentally modeled "BC" years. One hours before 01 Jan 0000, it was "-1" years but 365 days and 23h into the current day. + It was decided that the nanoseconds corresponds to the nanoseconds _into_ the current century. In other words, + a duration with centuries = -1 and nanoseconds = 0 is _a greater duration_ (further from zero) than centuries = -1 and nanoseconds = 1. + Duration zero minus one nanosecond returns a century of -1 and a nanosecond set to the number of nanoseconds in one century minus one. + That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter. + As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY. +2. It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function. + +(Python documentation hints) +:type string_repr: str +:rtype: Duration + + +#### Methods + + +##### Method `EPSILON` {#anise.time.Duration.EPSILON} + +> def EPSILON() + + +##### Method `MAX` {#anise.time.Duration.MAX} + +> def MAX() + + +##### Method `MIN` {#anise.time.Duration.MIN} + +> def MIN() + + +##### Method `MIN_NEGATIVE` {#anise.time.Duration.MIN_NEGATIVE} + +> def MIN_NEGATIVE() + + +##### Method `MIN_POSITIVE` {#anise.time.Duration.MIN_POSITIVE} + +> def MIN_POSITIVE() + + +##### Method `ZERO` {#anise.time.Duration.ZERO} + +> def ZERO() + + +##### Method `abs` {#anise.time.Duration.abs} + +> def abs( +> self, +> / +> ) + +Returns the absolute value of this duration +:rtype: Duration + + +##### Method `approx` {#anise.time.Duration.approx} + +> def approx( +> self, +> / +> ) + +Rounds this duration to the largest units represented in this duration. + +This is useful to provide an approximate human duration. Under the hood, this function uses round, +so the "tipping point" of the rounding is half way to the next increment of the greatest unit. +As shown below, one example is that 35 hours and 59 minutes rounds to 1 day, but 36 hours and 1 minute rounds +to 2 days because 2 days is closer to 36h 1 min than 36h 1 min is to 1 day. + +##### Example + +``` +use hifitime::{Duration, TimeUnits}; + +assert_eq!((2.hours() + 3.minutes()).approx(), 2.hours()); +assert_eq!((24.hours() + 3.minutes()).approx(), 1.days()); +assert_eq!((35.hours() + 59.minutes()).approx(), 1.days()); +assert_eq!((36.hours() + 1.minutes()).approx(), 2.days()); +assert_eq!((47.hours() + 3.minutes()).approx(), 2.days()); +assert_eq!((49.hours() + 3.minutes()).approx(), 2.days()); +``` + +:rtype: Duration + + +##### Method `ceil` {#anise.time.Duration.ceil} + +> def ceil( +> self, +> /, +> duration +> ) + +Ceils this duration to the closest provided duration + +This simply floors then adds the requested duration + +##### Example +``` +use hifitime::{Duration, TimeUnits}; + +let two_hours_three_min = 2.hours() + 3.minutes(); +assert_eq!(two_hours_three_min.ceil(1.hours()), 3.hours()); +assert_eq!(two_hours_three_min.ceil(30.minutes()), 2.hours() + 30.minutes()); +assert_eq!(two_hours_three_min.ceil(4.hours()), 4.hours()); +assert_eq!(two_hours_three_min.ceil(1.seconds()), two_hours_three_min + 1.seconds()); +assert_eq!(two_hours_three_min.ceil(1.hours() + 5.minutes()), 2.hours() + 10.minutes()); +``` + +:type duration: Duration +:rtype: Duration + + +##### Method `decompose` {#anise.time.Duration.decompose} + +> def decompose( +> self, +> / +> ) + +Decomposes a Duration in its sign, days, hours, minutes, seconds, ms, us, ns + +:rtype: typing.Tuple + + +##### Method `floor` {#anise.time.Duration.floor} + +> def floor( +> self, +> /, +> duration +> ) + +Floors this duration to the closest duration from the bottom + +##### Example +``` +use hifitime::{Duration, TimeUnits}; + +let two_hours_three_min = 2.hours() + 3.minutes(); +assert_eq!(two_hours_three_min.floor(1.hours()), 2.hours()); +assert_eq!(two_hours_three_min.floor(30.minutes()), 2.hours()); +// This is zero because we floor by a duration longer than the current duration, rounding it down +assert_eq!(two_hours_three_min.floor(4.hours()), 0.hours()); +assert_eq!(two_hours_three_min.floor(1.seconds()), two_hours_three_min); +assert_eq!(two_hours_three_min.floor(1.hours() + 1.minutes()), 2.hours() + 2.minutes()); +assert_eq!(two_hours_three_min.floor(1.hours() + 5.minutes()), 1.hours() + 5.minutes()); +``` + +:type duration: Duration +:rtype: Duration + + +##### Method `from_all_parts` {#anise.time.Duration.from_all_parts} + +> def from_all_parts( +> sign, +> days, +> hours, +> minutes, +> seconds, +> milliseconds, +> microseconds, +> nanoseconds +> ) + +Creates a new duration from its parts +:type sign: int +:type days: int +:type hours: int +:type minutes: int +:type seconds: int +:type milliseconds: int +:type microseconds: int +:type nanoseconds: int +:rtype: Duration + + +##### Method `from_parts` {#anise.time.Duration.from_parts} + +> def from_parts( +> centuries, +> nanoseconds +> ) + +Create a normalized duration from its parts +:type centuries: int +:type nanoseconds: int +:rtype: Duration + + +##### Method `from_total_nanoseconds` {#anise.time.Duration.from_total_nanoseconds} + +> def from_total_nanoseconds( +> nanos +> ) + +Creates a new Duration from its full nanoseconds +:type nanos: int +:rtype: Duration + + +##### Method `is_negative` {#anise.time.Duration.is_negative} + +> def is_negative( +> self, +> / +> ) + +Returns whether this is a negative or positive duration. +:rtype: bool + + +##### Method `max` {#anise.time.Duration.max} + +> def max( +> self, +> /, +> other +> ) + +Returns the maximum of the two durations. + +``` +use hifitime::TimeUnits; + +let d0 = 20.seconds(); +let d1 = 21.seconds(); + +assert_eq!(d1, d1.max(d0)); +assert_eq!(d1, d0.max(d1)); +``` + +:type other: Duration +:rtype: Duration + + +##### Method `min` {#anise.time.Duration.min} + +> def min( +> self, +> /, +> other +> ) + +Returns the minimum of the two durations. + +``` +use hifitime::TimeUnits; + +let d0 = 20.seconds(); +let d1 = 21.seconds(); + +assert_eq!(d0, d1.min(d0)); +assert_eq!(d0, d0.min(d1)); +``` + +:type other: Duration +:rtype: Duration + + +##### Method `round` {#anise.time.Duration.round} + +> def round( +> self, +> /, +> duration +> ) + +Rounds this duration to the closest provided duration + +This performs both a ceil and floor and returns the value which is the closest to current one. +##### Example +``` +use hifitime::{Duration, TimeUnits}; + +let two_hours_three_min = 2.hours() + 3.minutes(); +assert_eq!(two_hours_three_min.round(1.hours()), 2.hours()); +assert_eq!(two_hours_three_min.round(30.minutes()), 2.hours()); +assert_eq!(two_hours_three_min.round(4.hours()), 4.hours()); +assert_eq!(two_hours_three_min.round(1.seconds()), two_hours_three_min); +assert_eq!(two_hours_three_min.round(1.hours() + 5.minutes()), 2.hours() + 10.minutes()); +``` + +:type duration: Duration +:rtype: Duration + + +##### Method `signum` {#anise.time.Duration.signum} + +> def signum( +> self, +> / +> ) + +Returns the sign of this duration ++ 0 if the number is zero ++ 1 if the number is positive ++ -1 if the number is negative +:rtype: int + + +##### Method `to_parts` {#anise.time.Duration.to_parts} + +> def to_parts( +> self, +> / +> ) + +Returns the centuries and nanoseconds of this duration +NOTE: These items are not public to prevent incorrect durations from being created by modifying the values of the structure directly. +:rtype: typing.Tuple + + +##### Method `to_seconds` {#anise.time.Duration.to_seconds} + +> def to_seconds( +> self, +> / +> ) + +Returns this duration in seconds f64. +For high fidelity comparisons, it is recommended to keep using the Duration structure. +:rtype: float + + +##### Method `to_unit` {#anise.time.Duration.to_unit} + +> def to_unit( +> self, +> /, +> unit +> ) + +:type unit: Unit +:rtype: float + + +##### Method `total_nanoseconds` {#anise.time.Duration.total_nanoseconds} + +> def total_nanoseconds( +> self, +> / +> ) + +Returns the total nanoseconds in a signed 128 bit integer +:rtype: int + + +### Class `DurationError` {#anise.time.DurationError} + +> class DurationError( +> *args, +> **kwargs +> ) + + +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) + + +### Class `Epoch` {#anise.time.Epoch} + +> class Epoch( +> string_repr +> ) + +Defines a nanosecond-precision Epoch. + +Refer to the appropriate functions for initializing this Epoch from different time scales or representations. + +(Python documentation hints) +:type string_repr: str +:rtype: Epoch + + +#### Instance variables + + +##### Variable `duration` {#anise.time.Epoch.duration} + +:rtype: Duration + + +##### Variable `time_scale` {#anise.time.Epoch.time_scale} + +:rtype: TimeScale + + +#### Methods + + +##### Method `ceil` {#anise.time.Epoch.ceil} + +> def ceil( +> self, +> /, +> duration +> ) + +Ceils this epoch to the closest provided duration in the TAI time scale + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.ceil(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 18, 0, 0) +); + +// 45 minutes is a multiple of 3 minutes, hence this result +let e = Epoch::from_gregorian_tai(2022, 10, 3, 17, 44, 29, 898032665); +assert_eq!( + e.ceil(3.minutes()), + Epoch::from_gregorian_tai_hms(2022, 10, 3, 17, 45, 0) +); +``` +:type duration: Duration +:rtype: Epoch + + +##### Method `day_of_year` {#anise.time.Epoch.day_of_year} + +> def day_of_year( +> self, +> / +> ) + +Returns the number of days since the start of the year. +:rtype: float + + +##### Method `duration_in_year` {#anise.time.Epoch.duration_in_year} + +> def duration_in_year( +> self, +> / +> ) + +Returns the duration since the start of the year +:rtype: Duration + + +##### Method `floor` {#anise.time.Epoch.floor} + +> def floor( +> self, +> /, +> duration +> ) + +Floors this epoch to the closest provided duration + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.floor(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 0, 0) +); + +let e = Epoch::from_gregorian_tai(2022, 10, 3, 17, 44, 29, 898032665); +assert_eq!( + e.floor(3.minutes()), + Epoch::from_gregorian_tai_hms(2022, 10, 3, 17, 42, 0) +); +``` +:type duration: Duration +:rtype: Epoch + + +##### Method `from_bdt_days` {#anise.time.Epoch.from_bdt_days} + +> def from_bdt_days( +> days +> ) + +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `from_bdt_nanoseconds` {#anise.time.Epoch.from_bdt_nanoseconds} + +> def from_bdt_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +This may be useful for time keeping devices that use BDT as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `from_bdt_seconds` {#anise.time.Epoch.from_bdt_seconds} + +> def from_bdt_seconds( +> seconds +> ) + +Initialize an Epoch from the number of seconds since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `from_et_duration` {#anise.time.Epoch.from_et_duration} + +> def from_et_duration( +> duration_since_j2000 +> ) + +Initialize an Epoch from the Ephemeris Time duration past 2000 JAN 01 (J2000 reference) +:type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `from_et_seconds` {#anise.time.Epoch.from_et_seconds} + +> def from_et_seconds( +> seconds_since_j2000 +> ) + +Initialize an Epoch from the Ephemeris Time seconds past 2000 JAN 01 (J2000 reference) +:type seconds_since_j2000: float +:rtype: Epoch + + +##### Method `from_gpst_days` {#anise.time.Epoch.from_gpst_days} + +> def from_gpst_days( +> days +> ) + +Initialize an Epoch from the number of days since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `from_gpst_nanoseconds` {#anise.time.Epoch.from_gpst_nanoseconds} + +> def from_gpst_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use GPS as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `from_gpst_seconds` {#anise.time.Epoch.from_gpst_seconds} + +> def from_gpst_seconds( +> seconds +> ) + +Initialize an Epoch from the number of seconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `from_gregorian` {#anise.time.Epoch.from_gregorian} + +> def from_gregorian( +> year, +> month, +> day, +> hour, +> minute, +> second, +> nanos, +> time_scale +> ) + +Initialize from the Gregorian parts +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `from_gregorian_at_midnight` {#anise.time.Epoch.from_gregorian_at_midnight} + +> def from_gregorian_at_midnight( +> year, +> month, +> day, +> time_scale +> ) + +Initialize from the Gregorian parts, time set to midnight +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `from_gregorian_at_noon` {#anise.time.Epoch.from_gregorian_at_noon} + +> def from_gregorian_at_noon( +> year, +> month, +> day, +> time_scale +> ) + +Initialize from the Gregorian parts, time set to noon +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `from_gregorian_utc` {#anise.time.Epoch.from_gregorian_utc} + +> def from_gregorian_utc( +> year, +> month, +> day, +> hour, +> minute, +> second, +> nanos +> ) + +Builds an Epoch from the provided Gregorian date and time in TAI. If invalid date is provided, this function will panic. +Use maybe_from_gregorian_tai if unsure. + +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:rtype: Epoch + + +##### Method `from_gst_days` {#anise.time.Epoch.from_gst_days} + +> def from_gst_days( +> days +> ) + +Initialize an Epoch from the number of days since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type days: float +:rtype: Epoch + + +##### Method `from_gst_nanoseconds` {#anise.time.Epoch.from_gst_nanoseconds} + +> def from_gst_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the number of nanoseconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +This may be useful for time keeping devices that use GST as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `from_gst_seconds` {#anise.time.Epoch.from_gst_seconds} + +> def from_gst_seconds( +> seconds +> ) + +Initialize an Epoch from the number of seconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `from_jde_et` {#anise.time.Epoch.from_jde_et} + +> def from_jde_et( +> days +> ) + +Initialize from the JDE days +:type days: float +:rtype: Epoch + + +##### Method `from_jde_tai` {#anise.time.Epoch.from_jde_tai} + +> def from_jde_tai( +> days +> ) + +Initialize an Epoch from given JDE in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `from_jde_tdb` {#anise.time.Epoch.from_jde_tdb} + +> def from_jde_tdb( +> days +> ) + +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) in JD days +:type days: float +:rtype: Epoch + + +##### Method `from_jde_utc` {#anise.time.Epoch.from_jde_utc} + +> def from_jde_utc( +> days +> ) + +Initialize an Epoch from given JDE in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `from_mjd_tai` {#anise.time.Epoch.from_mjd_tai} + +> def from_mjd_tai( +> days +> ) + +Initialize an Epoch from given MJD in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `from_mjd_utc` {#anise.time.Epoch.from_mjd_utc} + +> def from_mjd_utc( +> days +> ) + +Initialize an Epoch from given MJD in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `from_ptp_duration` {#anise.time.Epoch.from_ptp_duration} + +> def from_ptp_duration( +> duration +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) duration since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type duration: Duration +:rtype: Epoch + + +##### Method `from_ptp_nanoseconds` {#anise.time.Epoch.from_ptp_nanoseconds} + +> def from_ptp_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) nanoseconds timestamp since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_ptp_seconds` {#anise.time.Epoch.from_ptp_seconds} + +> def from_ptp_seconds( +> seconds +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) second timestamp since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type seconds: float +:rtype: Epoch + + +##### Method `from_qzsst_days` {#anise.time.Epoch.from_qzsst_days} + +> def from_qzsst_days( +> days +> ) + +Initialize an Epoch from the number of days since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `from_qzsst_nanoseconds` {#anise.time.Epoch.from_qzsst_nanoseconds} + +> def from_qzsst_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use QZSS as a time source. +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_qzsst_seconds` {#anise.time.Epoch.from_qzsst_seconds} + +> def from_qzsst_seconds( +> seconds +> ) + +Initialize an Epoch from the number of seconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `from_tai_days` {#anise.time.Epoch.from_tai_days} + +> def from_tai_days( +> days +> ) + +Initialize an Epoch from the provided TAI days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `from_tai_duration` {#anise.time.Epoch.from_tai_duration} + +> def from_tai_duration( +> duration +> ) + +Creates a new Epoch from a Duration as the time difference between this epoch and TAI reference epoch. +:type duration: Duration +:rtype: Epoch + + +##### Method `from_tai_parts` {#anise.time.Epoch.from_tai_parts} + +> def from_tai_parts( +> centuries, +> nanoseconds +> ) + +Creates a new Epoch from its centuries and nanosecond since the TAI reference epoch. +:type centuries: int +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_tai_seconds` {#anise.time.Epoch.from_tai_seconds} + +> def from_tai_seconds( +> seconds +> ) + +Initialize an Epoch from the provided TAI seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `from_tdb_duration` {#anise.time.Epoch.from_tdb_duration} + +> def from_tdb_duration( +> duration_since_j2000 +> ) + +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI. + :type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `from_tdb_seconds` {#anise.time.Epoch.from_tdb_seconds} + +> def from_tdb_seconds( +> seconds_j2000 +> ) + +Initialize an Epoch from Dynamic Barycentric Time (TDB) seconds past 2000 JAN 01 midnight (difference than SPICE) +NOTE: This uses the ESA algorithm, which is a notch more complicated than the SPICE algorithm, but more precise. +In fact, SPICE algorithm is precise +/- 30 microseconds for a century whereas ESA algorithm should be exactly correct. +:type seconds_j2000: float +:rtype: Epoch + + +##### Method `from_tt_duration` {#anise.time.Epoch.from_tt_duration} + +> def from_tt_duration( +> duration +> ) + +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type duration: Duration +:rtype: Epoch + + +##### Method `from_tt_seconds` {#anise.time.Epoch.from_tt_seconds} + +> def from_tt_seconds( +> seconds +> ) + +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type seconds: float +:rtype: Epoch + + +##### Method `from_unix_milliseconds` {#anise.time.Epoch.from_unix_milliseconds} + +> def from_unix_milliseconds( +> milliseconds +> ) + +Initialize an Epoch from the provided UNIX millisecond timestamp since UTC midnight 1970 January 01. +:type milliseconds: float +:rtype: Epoch + + +##### Method `from_unix_seconds` {#anise.time.Epoch.from_unix_seconds} + +> def from_unix_seconds( +> seconds +> ) + +Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1970 January 01. +:type seconds: float +:rtype: Epoch + + +##### Method `from_utc_days` {#anise.time.Epoch.from_utc_days} + +> def from_utc_days( +> days +> ) + +Initialize an Epoch from the provided UTC days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `from_utc_seconds` {#anise.time.Epoch.from_utc_seconds} + +> def from_utc_seconds( +> seconds +> ) + +Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `fromdatetime` {#anise.time.Epoch.fromdatetime} + +> def fromdatetime( +> dt +> ) + +Builds an Epoch in UTC from the provided datetime after timezone correction if any is present. +:type dt: datetime.datetime +:rtype: Epoch + + +##### Method `hours` {#anise.time.Epoch.hours} + +> def hours( +> self, +> / +> ) + +Returns the hours of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `init_from_bdt_days` {#anise.time.Epoch.init_from_bdt_days} + +> def init_from_bdt_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_days instead +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_bdt_nanoseconds` {#anise.time.Epoch.init_from_bdt_nanoseconds} + +> def init_from_bdt_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_nanoseconds instead +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +This may be useful for time keeping devices that use BDT as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `init_from_bdt_seconds` {#anise.time.Epoch.init_from_bdt_seconds} + +> def init_from_bdt_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_seconds instead +Initialize an Epoch from the number of seconds since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_et_duration` {#anise.time.Epoch.init_from_et_duration} + +> def init_from_et_duration( +> duration_since_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_et\_duration instead +Initialize an Epoch from the Ephemeris Time duration past 2000 JAN 01 (J2000 reference) +:type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `init_from_et_seconds` {#anise.time.Epoch.init_from_et_seconds} + +> def init_from_et_seconds( +> seconds_since_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_et\_seconds instead +Initialize an Epoch from the Ephemeris Time seconds past 2000 JAN 01 (J2000 reference) +:type seconds_since_j2000: float +:rtype: Epoch + + +##### Method `init_from_gpst_days` {#anise.time.Epoch.init_from_gpst_days} + +> def init_from_gpst_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_days instead +Initialize an Epoch from the number of days since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_gpst_nanoseconds` {#anise.time.Epoch.init_from_gpst_nanoseconds} + +> def init_from_gpst_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_nanoseconds instead +Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use GPS as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `init_from_gpst_seconds` {#anise.time.Epoch.init_from_gpst_seconds} + +> def init_from_gpst_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_seconds instead +Initialize an Epoch from the number of seconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_gregorian` {#anise.time.Epoch.init_from_gregorian} + +> def init_from_gregorian( +> year, +> month, +> day, +> hour, +> minute, +> second, +> nanos, +> time_scale +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gregorian instead +Initialize from the Gregorian parts +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `init_from_gregorian_at_midnight` {#anise.time.Epoch.init_from_gregorian_at_midnight} + +> def init_from_gregorian_at_midnight( +> year, +> month, +> day, +> time_scale +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_at\_midnight instead +Initialize from the Gregorian parts, time set to midnight +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `init_from_gregorian_at_noon` {#anise.time.Epoch.init_from_gregorian_at_noon} + +> def init_from_gregorian_at_noon( +> year, +> month, +> day, +> time_scale +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_at\_noon instead +Initialize from the Gregorian parts, time set to noon +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + + +##### Method `init_from_gregorian_utc` {#anise.time.Epoch.init_from_gregorian_utc} + +> def init_from_gregorian_utc( +> year, +> month, +> day, +> hour, +> minute, +> second, +> nanos +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_utc instead +Builds an Epoch from the provided Gregorian date and time in TAI. If invalid date is provided, this function will panic. +Use maybe_from_gregorian_tai if unsure. + +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:rtype: Epoch + + +##### Method `init_from_gst_days` {#anise.time.Epoch.init_from_gst_days} + +> def init_from_gst_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gst\_days instead +Initialize an Epoch from the number of days since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_gst_nanoseconds` {#anise.time.Epoch.init_from_gst_nanoseconds} + +> def init_from_gst_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gst\_nanoseconds instead +Initialize an Epoch from the number of nanoseconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +This may be useful for time keeping devices that use GST as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `init_from_gst_seconds` {#anise.time.Epoch.init_from_gst_seconds} + +> def init_from_gst_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gst\_seconds instead +Initialize an Epoch from the number of seconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_jde_et` {#anise.time.Epoch.init_from_jde_et} + +> def init_from_jde_et( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_jde\_et instead +Initialize from the JDE days +:type days: float +:rtype: Epoch + + +##### Method `init_from_jde_tai` {#anise.time.Epoch.init_from_jde_tai} + +> def init_from_jde_tai( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_jde\_tai instead +Initialize an Epoch from given JDE in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `init_from_jde_tdb` {#anise.time.Epoch.init_from_jde_tdb} + +> def init_from_jde_tdb( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_jde\_tdb instead +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) in JD days +:type days: float +:rtype: Epoch + + +##### Method `init_from_jde_utc` {#anise.time.Epoch.init_from_jde_utc} + +> def init_from_jde_utc( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_jde\_utc instead +Initialize an Epoch from given JDE in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `init_from_mjd_tai` {#anise.time.Epoch.init_from_mjd_tai} + +> def init_from_mjd_tai( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_mjd\_tai instead +Initialize an Epoch from given MJD in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `init_from_mjd_utc` {#anise.time.Epoch.init_from_mjd_utc} + +> def init_from_mjd_utc( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_mjd\_utc instead +Initialize an Epoch from given MJD in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `init_from_qzsst_days` {#anise.time.Epoch.init_from_qzsst_days} + +> def init_from_qzsst_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_days instead +Initialize an Epoch from the number of days since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_qzsst_nanoseconds` {#anise.time.Epoch.init_from_qzsst_nanoseconds} + +> def init_from_qzsst_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_nanoseconds instead +Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use QZSS as a time source. +:type nanoseconds: int +:rtype: Epoch + + +##### Method `init_from_qzsst_seconds` {#anise.time.Epoch.init_from_qzsst_seconds} + +> def init_from_qzsst_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_seconds instead +Initialize an Epoch from the number of seconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_tai_days` {#anise.time.Epoch.init_from_tai_days} + +> def init_from_tai_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tai\_days instead +Initialize an Epoch from the provided TAI days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `init_from_tai_duration` {#anise.time.Epoch.init_from_tai_duration} + +> def init_from_tai_duration( +> duration +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tai\_duration instead +Creates a new Epoch from a Duration as the time difference between this epoch and TAI reference epoch. +:type duration: Duration +:rtype: Epoch + + +##### Method `init_from_tai_parts` {#anise.time.Epoch.init_from_tai_parts} + +> def init_from_tai_parts( +> centuries, +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tai\_parts instead +Creates a new Epoch from its centuries and nanosecond since the TAI reference epoch. +:type centuries: int +:type nanoseconds: int +:rtype: Epoch + + +##### Method `init_from_tai_seconds` {#anise.time.Epoch.init_from_tai_seconds} + +> def init_from_tai_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tai\_seconds instead +Initialize an Epoch from the provided TAI seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_tdb_duration` {#anise.time.Epoch.init_from_tdb_duration} + +> def init_from_tdb_duration( +> duration_since_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tdb\_duration instead +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI. + :type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `init_from_tdb_seconds` {#anise.time.Epoch.init_from_tdb_seconds} + +> def init_from_tdb_seconds( +> seconds_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tdb\_seconds instead +Initialize an Epoch from Dynamic Barycentric Time (TDB) seconds past 2000 JAN 01 midnight (difference than SPICE) +NOTE: This uses the ESA algorithm, which is a notch more complicated than the SPICE algorithm, but more precise. +In fact, SPICE algorithm is precise +/- 30 microseconds for a century whereas ESA algorithm should be exactly correct. +:type seconds_j2000: float +:rtype: Epoch + + +##### Method `init_from_tt_duration` {#anise.time.Epoch.init_from_tt_duration} + +> def init_from_tt_duration( +> duration +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tt\_duration instead +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type duration: Duration +:rtype: Epoch + + +##### Method `init_from_tt_seconds` {#anise.time.Epoch.init_from_tt_seconds} + +> def init_from_tt_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_tt\_seconds instead +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_unix_milliseconds` {#anise.time.Epoch.init_from_unix_milliseconds} + +> def init_from_unix_milliseconds( +> milliseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_unix\_milliseconds instead +Initialize an Epoch from the provided UNIX millisecond timestamp since UTC midnight 1970 January 01. +:type milliseconds: float +:rtype: Epoch + + +##### Method `init_from_unix_seconds` {#anise.time.Epoch.init_from_unix_seconds} + +> def init_from_unix_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_unix\_seconds instead +Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1970 January 01. +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_utc_days` {#anise.time.Epoch.init_from_utc_days} + +> def init_from_utc_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_utc\_days instead +Initialize an Epoch from the provided UTC days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `init_from_utc_seconds` {#anise.time.Epoch.init_from_utc_seconds} + +> def init_from_utc_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_utc\_seconds instead +Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `isoformat` {#anise.time.Epoch.isoformat} + +> def isoformat( +> self, +> / +> ) + +Equivalent to datetime.isoformat, and truncated to 23 chars, refer to for format options +:rtype: str + + +##### Method `leap_seconds` {#anise.time.Epoch.leap_seconds} + +> def leap_seconds( +> self, +> /, +> iers_only +> ) + +Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds and the SOFA scaling from 1960 to 1972, depending on flag. +Returns None if the epoch is before 1960, year at which UTC was defined. + +##### Why does this function return an Option when the other returns a value +This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. +:type iers_only: bool +:rtype: float + + +##### Method `leap_seconds_iers` {#anise.time.Epoch.leap_seconds_iers} + +> def leap_seconds_iers( +> self, +> / +> ) + +Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds. +:rtype: int + + +##### Method `leap_seconds_with_file` {#anise.time.Epoch.leap_seconds_with_file} + +> def leap_seconds_with_file( +> self, +> /, +> iers_only, +> provider +> ) + +Get the accumulated number of leap seconds up to this Epoch from the provided LeapSecondProvider. +Returns None if the epoch is before 1960, year at which UTC was defined. + +##### Why does this function return an Option when the other returns a value +This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. + +:type iers_only: bool +:type provider: LeapSecondsFile +:rtype: float + + +##### Method `max` {#anise.time.Epoch.max} + +> def max( +> self, +> /, +> other +> ) + +Returns the maximum of the two epochs. + +``` +use hifitime::Epoch; + +let e0 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 20); +let e1 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 21); + +assert_eq!(e1, e1.max(e0)); +assert_eq!(e1, e0.max(e1)); +``` + +_Note:_ this uses a pointer to self which will be copied immediately because Python requires a pointer. +:type other: Epoch +:rtype: Epoch + + +##### Method `microseconds` {#anise.time.Epoch.microseconds} + +> def microseconds( +> self, +> / +> ) + +Returns the microseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `milliseconds` {#anise.time.Epoch.milliseconds} + +> def milliseconds( +> self, +> / +> ) + +Returns the milliseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `min` {#anise.time.Epoch.min} + +> def min( +> self, +> /, +> other +> ) + +Returns the minimum of the two epochs. + +``` +use hifitime::Epoch; + +let e0 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 20); +let e1 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 21); + +assert_eq!(e0, e1.min(e0)); +assert_eq!(e0, e0.min(e1)); +``` + +_Note:_ this uses a pointer to self which will be copied immediately because Python requires a pointer. +:type other: Epoch +:rtype: Epoch + + +##### Method `minutes` {#anise.time.Epoch.minutes} + +> def minutes( +> self, +> / +> ) + +Returns the minutes of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `month_name` {#anise.time.Epoch.month_name} + +> def month_name( +> self, +> / +> ) + +:rtype: MonthName + + +##### Method `nanoseconds` {#anise.time.Epoch.nanoseconds} + +> def nanoseconds( +> self, +> / +> ) + +Returns the nanoseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `next` {#anise.time.Epoch.next} + +> def next( +> self, +> /, +> weekday +> ) + +Returns the next weekday. + +``` +use hifitime::prelude::*; + +let epoch = Epoch::from_gregorian_utc_at_midnight(1988, 1, 2); +assert_eq!(epoch.weekday_utc(), Weekday::Saturday); +assert_eq!(epoch.next(Weekday::Sunday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 3)); +assert_eq!(epoch.next(Weekday::Monday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 4)); +assert_eq!(epoch.next(Weekday::Tuesday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 5)); +assert_eq!(epoch.next(Weekday::Wednesday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 6)); +assert_eq!(epoch.next(Weekday::Thursday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 7)); +assert_eq!(epoch.next(Weekday::Friday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 8)); +assert_eq!(epoch.next(Weekday::Saturday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 9)); +``` +:type weekday: Weekday +:rtype: Epoch + + +##### Method `next_weekday_at_midnight` {#anise.time.Epoch.next_weekday_at_midnight} + +> def next_weekday_at_midnight( +> self, +> /, +> weekday +> ) + +:type weekday: Weekday +:rtype: Epoch + + +##### Method `next_weekday_at_noon` {#anise.time.Epoch.next_weekday_at_noon} + +> def next_weekday_at_noon( +> self, +> /, +> weekday +> ) + +:type weekday: Weekday +:rtype: Epoch + + +##### Method `precise_timescale_conversion` {#anise.time.Epoch.precise_timescale_conversion} + +> def precise_timescale_conversion( +> self, +> /, +> forward, +> reference_epoch, +> polynomial, +> target +> ) + +Converts this [Epoch] into targeted [TimeScale] using provided [Polynomial]. + +###### Input +- forward: whether this is forward or backward conversion. + For example, using GPST-UTC [Polynomial] + - GPST->UTC is the forward conversion + - UTC->GPST is the backward conversion +- reference_epoch: any reference [Epoch] for the provided [Polynomial]. + +While we support any time difference, it should remain short in pratice (a day at most, for precise applications). +- polynomial: that must be valid for this reference [Epoch], used in the equation `a0 + a1*dt + a2*dt² = GPST-UTC` for example. +- target: targetted [TimeScale] we will transition to. + +Example: +``` +use hifitime::{Epoch, TimeScale, Polynomial, Unit}; + +// random GPST Epoch for forward conversion to UTC +let t_gpst = Epoch::from_gregorian(2020, 01, 01, 0, 0, 0, 0, TimeScale::GPST); + +// Let's say we know the GPST-UTC polynomials for that day, +// They allow precise forward transition from GPST to UTC, +// and precise backward transition from UTC to GPST. +let gpst_utc_polynomials = Polynomial::from_constant_offset_nanoseconds(1.0); + +// This is the reference [Epoch] attached to the publication of these polynomials. +// You should use polynomials that remain valid and were provided recently (usually one day at most). +// Example: polynomials were published 1 hour ago. +let gpst_reference = t_gpst - 1.0 * Unit::Hour; + +// Forward conversion (to UTC) GPST - a0 + a1 *dt + a2*dt² = UTC +let t_utc = t_gpst.precise_timescale_conversion(true, gpst_reference, gpst_utc_polynomials, TimeScale::UTC) + .unwrap(); + +// Verify we did transition to UTC +assert_eq!(t_utc.time_scale, TimeScale::UTC); + +// Verify the resulting [Epoch] is the coarse GPST->UTC transition + fine correction +let reversed = t_utc.to_time_scale(TimeScale::GPST) + 1.0 * Unit::Nanosecond; +assert_eq!(reversed, t_gpst); + +// Apply the backward transition, from t_utc back to t_gpst. +// The timescale conversion works both ways: (from UTC) GPST = UTC + a0 + a1 *dt + a2*dt² +let backwards = t_utc.precise_timescale_conversion(false, gpst_reference, gpst_utc_polynomials, TimeScale::GPST) + .unwrap(); + +assert_eq!(backwards, t_gpst); + +// It is important to understand that your reference point does not have to be in the past. +// The only logic that should prevail is to always minimize interpolation gap. +// In other words, if you can access future interpolation information that would minimize the data gap, they should prevail. +// Example: +30' in the future. +let gpst_reference = t_gpst + 30.0 * Unit::Minute; + +// Forward conversion (to UTC) but using polynomials that were released 1 hour after t_gpst +let t_utc = t_gpst.precise_timescale_conversion(true, gpst_reference, gpst_utc_polynomials, TimeScale::UTC) + .unwrap(); + +// Verifications +assert_eq!(t_utc.time_scale, TimeScale::UTC); + +let reversed = t_utc.to_time_scale(TimeScale::GPST) + 1.0 * Unit::Nanosecond; +assert_eq!(reversed, t_gpst); +``` +:type forward: bool +:type reference_epoch: Epoch +:type polynomial: Polynomial +:type target: TimeScale +:rtype: Epoch + + +##### Method `previous` {#anise.time.Epoch.previous} + +> def previous( +> self, +> /, +> weekday +> ) + +Returns the next weekday. + +``` +use hifitime::prelude::*; + +let epoch = Epoch::from_gregorian_utc_at_midnight(1988, 1, 2); +assert_eq!(epoch.previous(Weekday::Friday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 1)); +assert_eq!(epoch.previous(Weekday::Thursday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 31)); +assert_eq!(epoch.previous(Weekday::Wednesday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 30)); +assert_eq!(epoch.previous(Weekday::Tuesday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 29)); +assert_eq!(epoch.previous(Weekday::Monday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 28)); +assert_eq!(epoch.previous(Weekday::Sunday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 27)); +assert_eq!(epoch.previous(Weekday::Saturday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 26)); +``` +:type weekday: Weekday +:rtype: Epoch + + +##### Method `previous_weekday_at_midnight` {#anise.time.Epoch.previous_weekday_at_midnight} + +> def previous_weekday_at_midnight( +> self, +> /, +> weekday +> ) + +:type weekday: Weekday +:rtype: Epoch + + +##### Method `previous_weekday_at_noon` {#anise.time.Epoch.previous_weekday_at_noon} + +> def previous_weekday_at_noon( +> self, +> /, +> weekday +> ) + +:type weekday: Weekday +:rtype: Epoch + + +##### Method `round` {#anise.time.Epoch.round} + +> def round( +> self, +> /, +> duration +> ) + +Rounds this epoch to the closest provided duration in TAI + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.round(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 18, 0, 0) +); +``` +:type duration: Duration +:rtype: Epoch + + +##### Method `seconds` {#anise.time.Epoch.seconds} + +> def seconds( +> self, +> / +> ) + +Returns the seconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `strftime` {#anise.time.Epoch.strftime} + +> def strftime( +> self, +> /, +> format_str +> ) + +Formats the epoch according to the given format string. Supports a subset of C89 and hifitime-specific format codes. Refer to for available format options. +:type format_str: str +:rtype: str + + +##### Method `strptime` {#anise.time.Epoch.strptime} + +> def strptime( +> epoch_str, +> format_str +> ) + +Equivalent to datetime.strptime, refer to for format options +:type epoch_str: str +:type format_str: str +:rtype: Epoch + + +##### Method `system_now` {#anise.time.Epoch.system_now} + +> def system_now() + +Returns the computer clock in UTC + +:rtype: Epoch + + +##### Method `timedelta` {#anise.time.Epoch.timedelta} + +> def timedelta( +> self, +> /, +> other +> ) + +Differences between two epochs +:type other: Duration +:rtype: Duration + + +##### Method `to_bdt_days` {#anise.time.Epoch.to_bdt_days} + +> def to_bdt_days( +> self, +> / +> ) + +Returns days past BDT (BeiDou) Time Epoch, defined as Jan 01 2006 UTC +(cf. ). +:rtype: float + + +##### Method `to_bdt_duration` {#anise.time.Epoch.to_bdt_duration} + +> def to_bdt_duration( +> self, +> / +> ) + +Returns [Duration](#anise.time.Duration "anise.time.Duration") past BDT (BeiDou) time Epoch. +:rtype: Duration + + +##### Method `to_bdt_nanoseconds` {#anise.time.Epoch.to_bdt_nanoseconds} + +> def to_bdt_nanoseconds( +> self, +> / +> ) + +Returns nanoseconds past BDT (BeiDou) Time Epoch, defined as Jan 01 2006 UTC +(cf. ). +NOTE: This function will return an error if the centuries past GST time are not zero. +:rtype: int + + +##### Method `to_bdt_seconds` {#anise.time.Epoch.to_bdt_seconds} + +> def to_bdt_seconds( +> self, +> / +> ) + +Returns seconds past BDT (BeiDou) Time Epoch +:rtype: float + + +##### Method `to_duration_in_time_scale` {#anise.time.Epoch.to_duration_in_time_scale} + +> def to_duration_in_time_scale( +> self, +> /, +> ts +> ) + +Returns this epoch with respect to the provided time scale. +This is needed to correctly perform duration conversions in dynamical time scales (e.g. TDB). +:type ts: TimeScale +:rtype: Duration + + +##### Method `to_et_centuries_since_j2000` {#anise.time.Epoch.to_et_centuries_since_j2000} + +> def to_et_centuries_since_j2000( +> self, +> / +> ) + +Returns the number of centuries since Ephemeris Time (ET) J2000 (used for Archinal et al. rotations) +:rtype: float + + +##### Method `to_et_days_since_j2000` {#anise.time.Epoch.to_et_days_since_j2000} + +> def to_et_days_since_j2000( +> self, +> / +> ) + +Returns the number of days since Ephemeris Time (ET) J2000 (used for Archinal et al. rotations) +:rtype: float + + +##### Method `to_et_duration` {#anise.time.Epoch.to_et_duration} + +> def to_et_duration( +> self, +> / +> ) + +Returns the duration between J2000 and the current epoch as per NAIF SPICE. + +##### Warning +The et2utc function of NAIF SPICE will assume that there are 9 leap seconds before 01 JAN 1972, +as this date introduces 10 leap seconds. At the time of writing, this does _not_ seem to be in +line with IERS and the documentation in the leap seconds list. + +In order to match SPICE, the as_et_duration() function will manually get rid of that difference. +:rtype: Duration + + +##### Method `to_et_seconds` {#anise.time.Epoch.to_et_seconds} + +> def to_et_seconds( +> self, +> / +> ) + +Returns the Ephemeris Time seconds past 2000 JAN 01 midnight, matches NASA/NAIF SPICE. +:rtype: float + + +##### Method `to_gpst_days` {#anise.time.Epoch.to_gpst_days} + +> def to_gpst_days( +> self, +> / +> ) + +Returns days past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float + + +##### Method `to_gpst_duration` {#anise.time.Epoch.to_gpst_duration} + +> def to_gpst_duration( +> self, +> / +> ) + +Returns [Duration](#anise.time.Duration "anise.time.Duration") past GPS time Epoch. +:rtype: Duration + + +##### Method `to_gpst_nanoseconds` {#anise.time.Epoch.to_gpst_nanoseconds} + +> def to_gpst_nanoseconds( +> self, +> / +> ) + +Returns nanoseconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +NOTE: This function will return an error if the centuries past GPST time are not zero. +:rtype: int + + +##### Method `to_gpst_seconds` {#anise.time.Epoch.to_gpst_seconds} + +> def to_gpst_seconds( +> self, +> / +> ) + +Returns seconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float + + +##### Method `to_gst_days` {#anise.time.Epoch.to_gst_days} + +> def to_gst_days( +> self, +> / +> ) + +Returns days past GST (Galileo) Time Epoch, +starting on August 21st 1999 Midnight UT +(cf. ). +:rtype: float + + +##### Method `to_gst_duration` {#anise.time.Epoch.to_gst_duration} + +> def to_gst_duration( +> self, +> / +> ) + +Returns [Duration](#anise.time.Duration "anise.time.Duration") past GST (Galileo) time Epoch. +:rtype: Duration + + +##### Method `to_gst_nanoseconds` {#anise.time.Epoch.to_gst_nanoseconds} + +> def to_gst_nanoseconds( +> self, +> / +> ) + +Returns nanoseconds past GST (Galileo) Time Epoch, starting on August 21st 1999 Midnight UT +(cf. ). +NOTE: This function will return an error if the centuries past GST time are not zero. +:rtype: int + + +##### Method `to_gst_seconds` {#anise.time.Epoch.to_gst_seconds} + +> def to_gst_seconds( +> self, +> / +> ) + +Returns seconds past GST (Galileo) Time Epoch +:rtype: float + + +##### Method `to_isoformat` {#anise.time.Epoch.to_isoformat} + +> def to_isoformat( +> self, +> / +> ) + +The standard ISO format of this epoch (six digits of subseconds) in the _current_ time scale, refer to for format options. +:rtype: str + + +##### Method `to_jde_et` {#anise.time.Epoch.to_jde_et} + +> def to_jde_et( +> self, +> /, +> unit +> ) + +:type unit: Unit +:rtype: float + + +##### Method `to_jde_et_days` {#anise.time.Epoch.to_jde_et_days} + +> def to_jde_et_days( +> self, +> / +> ) + +Returns the Ephemeris Time JDE past epoch +:rtype: float + + +##### Method `to_jde_et_duration` {#anise.time.Epoch.to_jde_et_duration} + +> def to_jde_et_duration( +> self, +> / +> ) + +:rtype: Duration + + +##### Method `to_jde_tai` {#anise.time.Epoch.to_jde_tai} + +> def to_jde_tai( +> self, +> /, +> unit +> ) + +Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) in desired Duration::Unit +:type unit: Unit +:rtype: float + + +##### Method `to_jde_tai_days` {#anise.time.Epoch.to_jde_tai_days} + +> def to_jde_tai_days( +> self, +> / +> ) + +Returns the Julian days from epoch 01 Jan -4713, 12:00 (noon) +as explained in "Fundamentals of astrodynamics and applications", Vallado et al. +4th edition, page 182, and on [Wikipedia](https://en.wikipedia.org/wiki/Julian_day). +:rtype: float + + +##### Method `to_jde_tai_duration` {#anise.time.Epoch.to_jde_tai_duration} + +> def to_jde_tai_duration( +> self, +> / +> ) + +Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) as a Duration +:rtype: Duration + + +##### Method `to_jde_tai_seconds` {#anise.time.Epoch.to_jde_tai_seconds} + +> def to_jde_tai_seconds( +> self, +> / +> ) + +Returns the Julian seconds in TAI. +:rtype: float + + +##### Method `to_jde_tdb_days` {#anise.time.Epoch.to_jde_tdb_days} + +> def to_jde_tdb_days( +> self, +> / +> ) + +Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI (cf. ) +:rtype: float + + +##### Method `to_jde_tdb_duration` {#anise.time.Epoch.to_jde_tdb_duration} + +> def to_jde_tdb_duration( +> self, +> / +> ) + +:rtype: Duration + + +##### Method `to_jde_tt_days` {#anise.time.Epoch.to_jde_tt_days} + +> def to_jde_tt_days( +> self, +> / +> ) + +Returns days past Julian epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float + + +##### Method `to_jde_tt_duration` {#anise.time.Epoch.to_jde_tt_duration} + +> def to_jde_tt_duration( +> self, +> / +> ) + +:rtype: Duration + + +##### Method `to_jde_utc_days` {#anise.time.Epoch.to_jde_utc_days} + +> def to_jde_utc_days( +> self, +> / +> ) + +Returns the Julian days in UTC. +:rtype: float + + +##### Method `to_jde_utc_duration` {#anise.time.Epoch.to_jde_utc_duration} + +> def to_jde_utc_duration( +> self, +> / +> ) + +Returns the Julian days in UTC as a [Duration](#anise.time.Duration "anise.time.Duration") +:rtype: Duration + + +##### Method `to_jde_utc_seconds` {#anise.time.Epoch.to_jde_utc_seconds} + +> def to_jde_utc_seconds( +> self, +> / +> ) + +Returns the Julian Days in UTC seconds. +:rtype: float + + +##### Method `to_mjd_tai` {#anise.time.Epoch.to_mjd_tai} + +> def to_mjd_tai( +> self, +> /, +> unit +> ) + +Returns this epoch as a duration in the requested units in MJD TAI +:type unit: Unit +:rtype: float + + +##### Method `to_mjd_tai_days` {#anise.time.Epoch.to_mjd_tai_days} + +> def to_mjd_tai_days( +> self, +> / +> ) + +as\_mjd\_days creates an Epoch from the provided Modified Julian Date in days as explained +[here](http://tycho.usno.navy.mil/mjd.html). MJD epoch is Modified Julian Day at 17 November 1858 at midnight. +:rtype: float + + +##### Method `to_mjd_tai_seconds` {#anise.time.Epoch.to_mjd_tai_seconds} + +> def to_mjd_tai_seconds( +> self, +> / +> ) + +Returns the Modified Julian Date in seconds TAI. +:rtype: float + + +##### Method `to_mjd_tt_days` {#anise.time.Epoch.to_mjd_tt_days} + +> def to_mjd_tt_days( +> self, +> / +> ) + +Returns days past Modified Julian epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float + + +##### Method `to_mjd_tt_duration` {#anise.time.Epoch.to_mjd_tt_duration} + +> def to_mjd_tt_duration( +> self, +> / +> ) + +:rtype: Duration + + +##### Method `to_mjd_utc` {#anise.time.Epoch.to_mjd_utc} + +> def to_mjd_utc( +> self, +> /, +> unit +> ) + +Returns the Modified Julian Date in the provided unit in UTC. +:type unit: Unit +:rtype: float + + +##### Method `to_mjd_utc_days` {#anise.time.Epoch.to_mjd_utc_days} + +> def to_mjd_utc_days( +> self, +> / +> ) + +Returns the Modified Julian Date in days UTC. +:rtype: float + + +##### Method `to_mjd_utc_seconds` {#anise.time.Epoch.to_mjd_utc_seconds} + +> def to_mjd_utc_seconds( +> self, +> / +> ) + +Returns the Modified Julian Date in seconds UTC. +:rtype: float + + +##### Method `to_nanoseconds_in_time_scale` {#anise.time.Epoch.to_nanoseconds_in_time_scale} + +> def to_nanoseconds_in_time_scale( +> self, +> /, +> time_scale +> ) + +Attempts to return the number of nanoseconds since the reference epoch of the provided time scale. +This will return an overflow error if more than one century has past since the reference epoch in the provided time scale. +If this is _not_ an issue, you should use epoch.to\_duration\_in\_time\_scale().to\_parts() to retrieve both the centuries and the nanoseconds +in that century. + +:type time_scale: TimeScale +:rtype: int + + +##### Method `to_qzsst_days` {#anise.time.Epoch.to_qzsst_days} + +> def to_qzsst_days( +> self, +> / +> ) + +Returns days past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float + + +##### Method `to_qzsst_duration` {#anise.time.Epoch.to_qzsst_duration} + +> def to_qzsst_duration( +> self, +> / +> ) + +Returns [Duration](#anise.time.Duration "anise.time.Duration") past QZSS time Epoch. +:rtype: Duration + + +##### Method `to_qzsst_nanoseconds` {#anise.time.Epoch.to_qzsst_nanoseconds} + +> def to_qzsst_nanoseconds( +> self, +> / +> ) + +Returns nanoseconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +NOTE: This function will return an error if the centuries past QZSST time are not zero. +:rtype: int + + +##### Method `to_qzsst_seconds` {#anise.time.Epoch.to_qzsst_seconds} + +> def to_qzsst_seconds( +> self, +> / +> ) + +Returns seconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float + + +##### Method `to_rfc3339` {#anise.time.Epoch.to_rfc3339} + +> def to_rfc3339( +> self, +> / +> ) + +Returns this epoch in UTC in the RFC3339 format +:rtype: str + + +##### Method `to_tai` {#anise.time.Epoch.to_tai} + +> def to_tai( +> self, +> /, +> unit +> ) + +Returns the epoch as a floating point value in the provided unit +:type unit: Unit +:rtype: float + + +##### Method `to_tai_days` {#anise.time.Epoch.to_tai_days} + +> def to_tai_days( +> self, +> / +> ) + +Returns the number of days since J1900 in TAI +:rtype: float + + +##### Method `to_tai_duration` {#anise.time.Epoch.to_tai_duration} + +> def to_tai_duration( +> self, +> / +> ) + +Returns this time in a Duration past J1900 counted in TAI +:rtype: Duration + + +##### Method `to_tai_parts` {#anise.time.Epoch.to_tai_parts} + +> def to_tai_parts( +> self, +> / +> ) + +Returns the TAI parts of this duration +:rtype: typing.Tuple + + +##### Method `to_tai_seconds` {#anise.time.Epoch.to_tai_seconds} + +> def to_tai_seconds( +> self, +> / +> ) + +Returns the number of TAI seconds since J1900 +:rtype: float + + +##### Method `to_tdb_centuries_since_j2000` {#anise.time.Epoch.to_tdb_centuries_since_j2000} + +> def to_tdb_centuries_since_j2000( +> self, +> / +> ) + +Returns the number of centuries since Dynamic Barycentric Time (TDB) J2000 (used for Archinal et al. rotations) +:rtype: float + + +##### Method `to_tdb_days_since_j2000` {#anise.time.Epoch.to_tdb_days_since_j2000} + +> def to_tdb_days_since_j2000( +> self, +> / +> ) + +Returns the number of days since Dynamic Barycentric Time (TDB) J2000 (used for Archinal et al. rotations) +:rtype: float + + +##### Method `to_tdb_duration` {#anise.time.Epoch.to_tdb_duration} + +> def to_tdb_duration( +> self, +> / +> ) + +Returns the Dynamics Barycentric Time (TDB) as a high precision Duration since J2000 + +###### Algorithm +Given the embedded sine functions in the equation to compute the difference between TDB and TAI from the number of TDB seconds +past J2000, one cannot solve the revert the operation analytically. Instead, we iterate until the value no longer changes. + +1. Assume that the TAI duration is in fact the TDB seconds from J2000. +2. Offset to J2000 because [Epoch](#anise.time.Epoch "anise.time.Epoch") stores everything in the J1900 but the TDB duration is in J2000. +3. Compute the offset g due to the TDB computation with the current value of the TDB seconds (defined in step 1). +4. Subtract that offset to the latest TDB seconds and store this as a new candidate for the true TDB seconds value. +5. Compute the difference between this candidate and the previous one. If the difference is less than one nanosecond, stop iteration. +6. Set the new candidate as the TDB seconds since J2000 and loop until step 5 breaks the loop, or we've done five iterations. +7. At this stage, we have a good approximation of the TDB seconds since J2000. +8. Reverse the algorithm given that approximation: compute the g offset, compute the difference between TDB and TAI, add the TT offset (32.184 s), and offset by the difference between J1900 and J2000. + +:rtype: Duration + + +##### Method `to_tdb_seconds` {#anise.time.Epoch.to_tdb_seconds} + +> def to_tdb_seconds( +> self, +> / +> ) + +Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI (cf. ) +:rtype: float + + +##### Method `to_time_of_week` {#anise.time.Epoch.to_time_of_week} + +> def to_time_of_week( +> self, +> / +> ) + +Converts this epoch into the time of week, represented as a rolling week counter into that time scale +and the number of nanoseconds elapsed in current week (since closest Sunday midnight). +This is usually how GNSS receivers describe a timestamp. +:rtype: typing.Tuple[int] + + +##### Method `to_time_scale` {#anise.time.Epoch.to_time_scale} + +> def to_time_scale( +> self, +> /, +> ts +> ) + +Converts self to another time scale + +As per the [Rust naming convention](https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv), +this borrows an Epoch and returns an owned Epoch. + +:type ts: TimeScale +:rtype: Epoch + + +##### Method `to_tt_centuries_j2k` {#anise.time.Epoch.to_tt_centuries_j2k} + +> def to_tt_centuries_j2k( +> self, +> / +> ) + +Returns the centuries passed J2000 TT +:rtype: float + + +##### Method `to_tt_days` {#anise.time.Epoch.to_tt_days} + +> def to_tt_days( +> self, +> / +> ) + +Returns days past TAI epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float + + +##### Method `to_tt_duration` {#anise.time.Epoch.to_tt_duration} + +> def to_tt_duration( +> self, +> / +> ) + +Returns [Duration](#anise.time.Duration "anise.time.Duration") past TAI epoch in Terrestrial Time (TT). +:rtype: Duration + + +##### Method `to_tt_seconds` {#anise.time.Epoch.to_tt_seconds} + +> def to_tt_seconds( +> self, +> / +> ) + +Returns seconds past TAI epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float + + +##### Method `to_tt_since_j2k` {#anise.time.Epoch.to_tt_since_j2k} + +> def to_tt_since_j2k( +> self, +> / +> ) + +Returns the duration past J2000 TT +:rtype: Duration + + +##### Method `to_unix` {#anise.time.Epoch.to_unix} + +> def to_unix( +> self, +> /, +> unit +> ) + +Returns the duration since the UNIX epoch in the provided unit. +:type unit: Unit +:rtype: float + + +##### Method `to_unix_days` {#anise.time.Epoch.to_unix_days} + +> def to_unix_days( +> self, +> / +> ) + +Returns the number days since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float + + +##### Method `to_unix_duration` {#anise.time.Epoch.to_unix_duration} + +> def to_unix_duration( +> self, +> / +> ) + +Returns the Duration since the UNIX epoch UTC midnight 01 Jan 1970. +:rtype: Duration + + +##### Method `to_unix_milliseconds` {#anise.time.Epoch.to_unix_milliseconds} + +> def to_unix_milliseconds( +> self, +> / +> ) + +Returns the number milliseconds since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float + + +##### Method `to_unix_seconds` {#anise.time.Epoch.to_unix_seconds} + +> def to_unix_seconds( +> self, +> / +> ) + +Returns the number seconds since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float + + +##### Method `to_utc` {#anise.time.Epoch.to_utc} + +> def to_utc( +> self, +> /, +> unit +> ) + +Returns the number of UTC seconds since the TAI epoch +:type unit: Unit +:rtype: float + + +##### Method `to_utc_days` {#anise.time.Epoch.to_utc_days} + +> def to_utc_days( +> self, +> / +> ) + +Returns the number of UTC days since the TAI epoch +:rtype: float + + +##### Method `to_utc_duration` {#anise.time.Epoch.to_utc_duration} + +> def to_utc_duration( +> self, +> / +> ) + +Returns this time in a Duration past J1900 counted in UTC +:rtype: Duration + + +##### Method `to_utc_seconds` {#anise.time.Epoch.to_utc_seconds} + +> def to_utc_seconds( +> self, +> / +> ) + +Returns the number of UTC seconds since the TAI epoch +:rtype: float + + +##### Method `todatetime` {#anise.time.Epoch.todatetime} + +> def todatetime( +> self, +> / +> ) + +Returns a Python datetime object from this Epoch (truncating the nanoseconds away) +:rtype: datetime.datetime + + +##### Method `weekday` {#anise.time.Epoch.weekday} + +> def weekday( +> self, +> / +> ) + +Returns weekday (uses the TAI representation for this calculation). +:rtype: Weekday + + +##### Method `weekday_in_time_scale` {#anise.time.Epoch.weekday_in_time_scale} + +> def weekday_in_time_scale( +> self, +> /, +> time_scale +> ) + +Returns the weekday in provided time scale **ASSUMING** that the reference epoch of that time scale is a Monday. +You _probably_ do not want to use this. You probably either want weekday() or weekday\_utc(). +Several time scales do _not_ have a reference day that's on a Monday, e.g. BDT. +:type time_scale: TimeScale +:rtype: Weekday + + +##### Method `weekday_utc` {#anise.time.Epoch.weekday_utc} + +> def weekday_utc( +> self, +> / +> ) + +Returns weekday in UTC timescale +:rtype: Weekday + + +##### Method `year` {#anise.time.Epoch.year} + +> def year( +> self, +> / +> ) + +Returns the number of Gregorian years of this epoch in the current time scale. +:rtype: int + + +##### Method `year_days_of_year` {#anise.time.Epoch.year_days_of_year} + +> def year_days_of_year( +> self, +> / +> ) + +Returns the year and the days in the year so far (days of year). +:rtype: typing.Tuple + + +### Class `HifitimeError` {#anise.time.HifitimeError} + +> class HifitimeError( +> *args, +> **kwargs +> ) + + +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) + + +### Class `LatestLeapSeconds` {#anise.time.LatestLeapSeconds} + +> class LatestLeapSeconds + +List of leap seconds from . +This list corresponds the number of seconds in TAI to the UTC offset and to whether it was an announced leap second or not. +The unannoucned leap seconds come from dat.c in the SOFA library. + + +### Class `LeapSecondsFile` {#anise.time.LeapSecondsFile} + +> class LeapSecondsFile( +> path +> ) + +A leap second provider that uses an IERS formatted leap seconds file. + +(Python documentation hints) +:type path: str +:rtype: LeapSecondsFile + + +### Class `MonthName` {#anise.time.MonthName} + +> class MonthName( +> ... +> ) + + +#### Class variables + + +##### Variable `April` {#anise.time.MonthName.April} + + +##### Variable `August` {#anise.time.MonthName.August} + + +##### Variable `December` {#anise.time.MonthName.December} + + +##### Variable `February` {#anise.time.MonthName.February} + + +##### Variable `January` {#anise.time.MonthName.January} + + +##### Variable `July` {#anise.time.MonthName.July} + + +##### Variable `June` {#anise.time.MonthName.June} + + +##### Variable `March` {#anise.time.MonthName.March} + + +##### Variable `May` {#anise.time.MonthName.May} + + +##### Variable `November` {#anise.time.MonthName.November} + + +##### Variable `October` {#anise.time.MonthName.October} + + +##### Variable `September` {#anise.time.MonthName.September} + + +### Class `ParsingError` {#anise.time.ParsingError} + +> class ParsingError( +> *args, +> **kwargs +> ) + + +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) + + +### Class `Polynomial` {#anise.time.Polynomial} + +> class Polynomial( +> ... +> ) + +Interpolation [Polynomial] used for example in [TimeScale] +maintenance, precise monitoring or conversions. + +(Python documentation hints) +:type constant: Duration +:type rate: Duration +:type accel: Duration +:rtype: Polynomial + + +#### Methods + + +##### Method `correction_duration` {#anise.time.Polynomial.correction_duration} + +> def correction_duration( +> self, +> /, +> time_interval +> ) + +Calculate the correction (as [Duration] once again) from [Self] and given +the interpolation time interval +:type time_interval: Duration +:rtype: Duration + + +##### Method `from_constant_offset` {#anise.time.Polynomial.from_constant_offset} + +> def from_constant_offset( +> constant +> ) + +Create a [Polynomial] structure that is only made of a static offset +:type constant: Duration +:rtype: Polynomial + + +##### Method `from_constant_offset_nanoseconds` {#anise.time.Polynomial.from_constant_offset_nanoseconds} + +> def from_constant_offset_nanoseconds( +> nanos +> ) + +Create a [Polynomial] structure from a static offset expressed in nanoseconds +:type nanos: float +:rtype: Polynomial + + +##### Method `from_offset_and_rate` {#anise.time.Polynomial.from_offset_and_rate} + +> def from_offset_and_rate( +> constant, +> rate +> ) + +Create a [Polynomial] structure from both static offset and rate of change: +:type constant: Duration +:type rate: Duration +:rtype: Polynomial + + +##### Method `from_offset_rate_nanoseconds` {#anise.time.Polynomial.from_offset_rate_nanoseconds} + +> def from_offset_rate_nanoseconds( +> offset_ns, +> drift_ns_s +> ) + +Create a [Polynomial] structure from a static offset and drift, in nanoseconds and nanoseconds.s⁻¹ +:type offset_ns: float +:type drift_ns_s: float +:rtype: Polynomial + + +### Class `TimeScale` {#anise.time.TimeScale} + +> class TimeScale( +> ... +> ) + +Enum of the different time systems available + + +#### Class variables + + +##### Variable `BDT` {#anise.time.TimeScale.BDT} + + +##### Variable `ET` {#anise.time.TimeScale.ET} + + +##### Variable `GPST` {#anise.time.TimeScale.GPST} + + +##### Variable `GST` {#anise.time.TimeScale.GST} + + +##### Variable `QZSST` {#anise.time.TimeScale.QZSST} + + +##### Variable `TAI` {#anise.time.TimeScale.TAI} + + +##### Variable `TDB` {#anise.time.TimeScale.TDB} + + +##### Variable `TT` {#anise.time.TimeScale.TT} + + +##### Variable `UTC` {#anise.time.TimeScale.UTC} + + +#### Methods + + +##### Method `uses_leap_seconds` {#anise.time.TimeScale.uses_leap_seconds} + +> def uses_leap_seconds( +> self, +> / +> ) + +Returns true if self takes leap seconds into account +:rtype: bool + + +### Class `TimeSeries` {#anise.time.TimeSeries} + +> class TimeSeries( +> start, +> end, +> step, +> inclusive +> ) + +An iterator of a sequence of evenly spaced Epochs. + +(Python documentation hints) +:type start: Epoch +:type end: Epoch +:type step: Duration +:type inclusive: bool +:rtype: TimeSeries + + +### Class `Unit` {#anise.time.Unit} + +> class Unit( +> ... +> ) + +An Enum to perform time unit conversions. + + +#### Class variables + + +##### Variable `Century` {#anise.time.Unit.Century} + + +##### Variable `Day` {#anise.time.Unit.Day} + + +##### Variable `Hour` {#anise.time.Unit.Hour} + + +##### Variable `Microsecond` {#anise.time.Unit.Microsecond} + + +##### Variable `Millisecond` {#anise.time.Unit.Millisecond} + + +##### Variable `Minute` {#anise.time.Unit.Minute} + + +##### Variable `Nanosecond` {#anise.time.Unit.Nanosecond} + + +##### Variable `Second` {#anise.time.Unit.Second} + + +##### Variable `Week` {#anise.time.Unit.Week} + + +#### Methods + + +##### Method `from_seconds` {#anise.time.Unit.from_seconds} + +> def from_seconds( +> self, +> / +> ) + + +##### Method `in_seconds` {#anise.time.Unit.in_seconds} + +> def in_seconds( +> self, +> / +> ) + + +### Class `Ut1Provider` {#anise.time.Ut1Provider} + +> class Ut1Provider + +A structure storing all of the TAI-UT1 data + + +### Class `Weekday` {#anise.time.Weekday} + +> class Weekday( +> ... +> ) + + +#### Class variables + + +##### Variable `Friday` {#anise.time.Weekday.Friday} + + +##### Variable `Monday` {#anise.time.Weekday.Monday} + + +##### Variable `Saturday` {#anise.time.Weekday.Saturday} + + +##### Variable `Sunday` {#anise.time.Weekday.Sunday} + + +##### Variable `Thursday` {#anise.time.Weekday.Thursday} + + +##### Variable `Tuesday` {#anise.time.Weekday.Tuesday} + + +##### Variable `Wednesday` {#anise.time.Weekday.Wednesday} + + +# Module `anise.utils` {#anise.utils} + + +## Functions + + +### Function `convert_fk` {#anise.utils.convert_fk} + +> def convert_fk( +> fk_file_path, +> anise_output_path, +> show_comments=None, +> overwrite=None +> ) + +Converts a KPL/FK file, that defines frame constants like fixed rotations, and frame name to ID mappings into the EulerParameterDataSet equivalent ANISE file. +KPL/FK files must be converted into "PCA" (Planetary Constant ANISE) files before being loaded into ANISE. + +:type fk_file_path: str +:type anise_output_path: str +:type show_comments: bool, optional +:type overwrite: bool, optional +:rtype: None + + +### Function `convert_tpc` {#anise.utils.convert_tpc} + +> def convert_tpc( +> pck_file_path, +> gm_file_path, +> anise_output_path, +> overwrite=None +> ) + +Converts two KPL/TPC files, one defining the planetary constants as text, and the other defining the gravity parameters, into the PlanetaryDataSet equivalent ANISE file. +KPL/TPC files must be converted into "PCA" (Planetary Constant ANISE) files before being loaded into ANISE. + +:type pck_file_path: str +:type gm_file_path: str +:type anise_output_path: str +:type overwrite: bool, optional +:rtype: None ----- -Generated by *pdoc* 0.10.0 (). +Generated by *pdoc* 0.11.6 (). diff --git a/docs/anise/reference/api/python/rotation.md b/docs/anise/reference/api/python/rotation.md new file mode 100644 index 0000000..30897ed --- /dev/null +++ b/docs/anise/reference/api/python/rotation.md @@ -0,0 +1,176 @@ +# Module `anise.rotation` {#anise.rotation} + + +## Classes + + +### Class `DCM` {#anise.rotation.DCM} + +> class DCM( +> np_rot_mat, +> from_id, +> to_id, +> np_rot_mat_dt=None +> ) + +Defines a direction cosine matrix from one frame ID to another frame ID, optionally with its time derivative. +It provides a number of run-time checks that prevent invalid rotations. + +:type np_rot_mat: numpy.array +:type from_id: int +:type to_id: int +:type np_rot_mat_dt: numpy.array, optional +:rtype: DCM + + +#### Instance variables + + +##### Variable `from_id` {#anise.rotation.DCM.from_id} + +:rtype: int + + +##### Variable `rot_mat` {#anise.rotation.DCM.rot_mat} + +:rtype: numpy.array + + +##### Variable `rot_mat_dt` {#anise.rotation.DCM.rot_mat_dt} + +:rtype: numpy.array + + +##### Variable `to_id` {#anise.rotation.DCM.to_id} + +:rtype: int + + +#### Methods + + +##### Method `from_identity` {#anise.rotation.DCM.from_identity} + +> def from_identity( +> from_id, +> to_id +> ) + +Builds an identity rotation. + +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r1` {#anise.rotation.DCM.from_r1} + +> def from_r1( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the X axis. + +Source: euler1 function from Baslisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r2` {#anise.rotation.DCM.from_r2} + +> def from_r2( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the Y axis. + +Source: euler2 function from Basilisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `from_r3` {#anise.rotation.DCM.from_r3} + +> def from_r3( +> angle_rad, +> from_id, +> to_id +> ) + +Returns a rotation matrix for a rotation about the Z axis. + +Source: euler3 function from Basilisk + +:type angle_rad: float +:type from_id: int +:type to_id: int +:rtype: DCM + + +##### Method `get_state_dcm` {#anise.rotation.DCM.get_state_dcm} + +> def get_state_dcm( +> self, +> / +> ) + +Returns the 6x6 DCM to rotate a state. If the time derivative of this DCM is defined, this 6x6 accounts for the transport theorem. +Warning: you MUST manually install numpy to call this function. +:rtype: numpy.array + + +##### Method `is_identity` {#anise.rotation.DCM.is_identity} + +> def is_identity( +> self, +> / +> ) + +Returns whether this rotation is identity, checking first the frames and then the rotation matrix (but ignores its time derivative) + +:rtype: bool + + +##### Method `is_valid` {#anise.rotation.DCM.is_valid} + +> def is_valid( +> self, +> /, +> unit_tol, +> det_tol +> ) + +Returns whether the rot\_mat of this DCM is a valid rotation matrix. +The criteria for validity are: +-- The columns of the matrix are unit vectors, within a specified tolerance (unit_tol). +-- The determinant of the matrix formed by unitizing the columns of the input matrix is 1, within a specified tolerance. This criterion ensures that the columns of the matrix are nearly orthogonal, and that they form a right-handed basis (det_tol). +[Source: SPICE's rotation.req](https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/rotation.html#Validating%20a%20rotation%20matrix) + +:type unit_tol: float +:type det_tol: float +:rtype: bool + + +##### Method `transpose` {#anise.rotation.DCM.transpose} + +> def transpose( +> self, +> / +> ) + +Returns the transpose of this DCM + +:rtype: DCM + +----- +Generated by *pdoc* 0.11.6 (). diff --git a/docs/anise/reference/api/python/time.md b/docs/anise/reference/api/python/time.md index 44e031c..f49f85f 100644 --- a/docs/anise/reference/api/python/time.md +++ b/docs/anise/reference/api/python/time.md @@ -1,10 +1,10 @@ -# Module `time` +# Module `anise.time` {#anise.time} ## Classes -### Class `Duration` +### Class `Duration` {#anise.time.Duration} > class Duration( > string_repr @@ -14,48 +14,52 @@ Defines generally usable durations for nanosecond precision valid for 32,768 cen **Important conventions:** 1. The negative durations can be mentally modeled "BC" years. One hours before 01 Jan 0000, it was "-1" years but 365 days and 23h into the current day. -It was decided that the nanoseconds corresponds to the nanoseconds _into_ the current century. In other words, -a duration with centuries = -1 and nanoseconds = 0 is _a greater duration_ (further from zero) than centuries = -1 and nanoseconds = 1. -Duration zero minus one nanosecond returns a century of -1 and a nanosecond set to the number of nanoseconds in one century minus one. -That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter. -As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY. + It was decided that the nanoseconds corresponds to the nanoseconds _into_ the current century. In other words, + a duration with centuries = -1 and nanoseconds = 0 is _a greater duration_ (further from zero) than centuries = -1 and nanoseconds = 1. + Duration zero minus one nanosecond returns a century of -1 and a nanosecond set to the number of nanoseconds in one century minus one. + That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter. + As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY. 2. It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function. +(Python documentation hints) +:type string_repr: str +:rtype: Duration + #### Methods -##### Method `EPSILON` +##### Method `EPSILON` {#anise.time.Duration.EPSILON} > def EPSILON() -##### Method `MAX` +##### Method `MAX` {#anise.time.Duration.MAX} > def MAX() -##### Method `MIN` +##### Method `MIN` {#anise.time.Duration.MIN} > def MIN() -##### Method `MIN_NEGATIVE` +##### Method `MIN_NEGATIVE` {#anise.time.Duration.MIN_NEGATIVE} > def MIN_NEGATIVE() -##### Method `MIN_POSITIVE` +##### Method `MIN_POSITIVE` {#anise.time.Duration.MIN_POSITIVE} > def MIN_POSITIVE() -##### Method `ZERO` +##### Method `ZERO` {#anise.time.Duration.ZERO} > def ZERO() -##### Method `abs` +##### Method `abs` {#anise.time.Duration.abs} > def abs( > self, @@ -63,9 +67,10 @@ As such, the largest negative duration that can be represented sets the centurie > ) Returns the absolute value of this duration +:rtype: Duration -##### Method `approx` +##### Method `approx` {#anise.time.Duration.approx} > def approx( > self, @@ -92,8 +97,10 @@ assert_eq!((47.hours() + 3.minutes()).approx(), 2.days()); assert_eq!((49.hours() + 3.minutes()).approx(), 2.days()); ``` +:rtype: Duration + -##### Method `ceil` +##### Method `ceil` {#anise.time.Duration.ceil} > def ceil( > self, @@ -117,8 +124,11 @@ assert_eq!(two_hours_three_min.ceil(1.seconds()), two_hours_three_min + 1.second assert_eq!(two_hours_three_min.ceil(1.hours() + 5.minutes()), 2.hours() + 10.minutes()); ``` +:type duration: Duration +:rtype: Duration + -##### Method `decompose` +##### Method `decompose` {#anise.time.Duration.decompose} > def decompose( > self, @@ -127,8 +137,10 @@ assert_eq!(two_hours_three_min.ceil(1.hours() + 5.minutes()), 2.hours() + 10.min Decomposes a Duration in its sign, days, hours, minutes, seconds, ms, us, ns +:rtype: typing.Tuple + -##### Method `floor` +##### Method `floor` {#anise.time.Duration.floor} > def floor( > self, @@ -152,8 +164,11 @@ assert_eq!(two_hours_three_min.floor(1.hours() + 1.minutes()), 2.hours() + 2.min assert_eq!(two_hours_three_min.floor(1.hours() + 5.minutes()), 1.hours() + 5.minutes()); ``` +:type duration: Duration +:rtype: Duration + -##### Method `from_all_parts` +##### Method `from_all_parts` {#anise.time.Duration.from_all_parts} > def from_all_parts( > sign, @@ -167,9 +182,18 @@ assert_eq!(two_hours_three_min.floor(1.hours() + 5.minutes()), 1.hours() + 5.min > ) Creates a new duration from its parts +:type sign: int +:type days: int +:type hours: int +:type minutes: int +:type seconds: int +:type milliseconds: int +:type microseconds: int +:type nanoseconds: int +:rtype: Duration -##### Method `from_parts` +##### Method `from_parts` {#anise.time.Duration.from_parts} > def from_parts( > centuries, @@ -177,16 +201,23 @@ Creates a new duration from its parts > ) Create a normalized duration from its parts +:type centuries: int +:type nanoseconds: int +:rtype: Duration -##### Method `from_total_nanoseconds` +##### Method `from_total_nanoseconds` {#anise.time.Duration.from_total_nanoseconds} > def from_total_nanoseconds( > nanos > ) +Creates a new Duration from its full nanoseconds +:type nanos: int +:rtype: Duration + -##### Method `is_negative` +##### Method `is_negative` {#anise.time.Duration.is_negative} > def is_negative( > self, @@ -194,9 +225,10 @@ Create a normalized duration from its parts > ) Returns whether this is a negative or positive duration. +:rtype: bool -##### Method `max` +##### Method `max` {#anise.time.Duration.max} > def max( > self, @@ -216,8 +248,11 @@ assert_eq!(d1, d1.max(d0)); assert_eq!(d1, d0.max(d1)); ``` +:type other: Duration +:rtype: Duration + -##### Method `min` +##### Method `min` {#anise.time.Duration.min} > def min( > self, @@ -237,8 +272,11 @@ assert_eq!(d0, d1.min(d0)); assert_eq!(d0, d0.min(d1)); ``` +:type other: Duration +:rtype: Duration + -##### Method `round` +##### Method `round` {#anise.time.Duration.round} > def round( > self, @@ -261,8 +299,11 @@ assert_eq!(two_hours_three_min.round(1.seconds()), two_hours_three_min); assert_eq!(two_hours_three_min.round(1.hours() + 5.minutes()), 2.hours() + 10.minutes()); ``` +:type duration: Duration +:rtype: Duration + -##### Method `signum` +##### Method `signum` {#anise.time.Duration.signum} > def signum( > self, @@ -273,9 +314,10 @@ Returns the sign of this duration + 0 if the number is zero + 1 if the number is positive + -1 if the number is negative +:rtype: int -##### Method `to_parts` +##### Method `to_parts` {#anise.time.Duration.to_parts} > def to_parts( > self, @@ -284,9 +326,10 @@ Returns the sign of this duration Returns the centuries and nanoseconds of this duration NOTE: These items are not public to prevent incorrect durations from being created by modifying the values of the structure directly. +:rtype: typing.Tuple -##### Method `to_seconds` +##### Method `to_seconds` {#anise.time.Duration.to_seconds} > def to_seconds( > self, @@ -295,9 +338,10 @@ NOTE: These items are not public to prevent incorrect durations from being creat Returns this duration in seconds f64. For high fidelity comparisons, it is recommended to keep using the Duration structure. +:rtype: float -##### Method `to_unit` +##### Method `to_unit` {#anise.time.Duration.to_unit} > def to_unit( > self, @@ -305,8 +349,11 @@ For high fidelity comparisons, it is recommended to keep using the Duration stru > unit > ) +:type unit: Unit +:rtype: float + -##### Method `total_nanoseconds` +##### Method `total_nanoseconds` {#anise.time.Duration.total_nanoseconds} > def total_nanoseconds( > self, @@ -314,9 +361,24 @@ For high fidelity comparisons, it is recommended to keep using the Duration stru > ) Returns the total nanoseconds in a signed 128 bit integer +:rtype: int + + +### Class `DurationError` {#anise.time.DurationError} + +> class DurationError( +> *args, +> **kwargs +> ) + + +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) -### Class `Epoch` +### Class `Epoch` {#anise.time.Epoch} > class Epoch( > string_repr @@ -326,11 +388,59 @@ Defines a nanosecond-precision Epoch. Refer to the appropriate functions for initializing this Epoch from different time scales or representations. +(Python documentation hints) +:type string_repr: str +:rtype: Epoch + + +#### Instance variables + + +##### Variable `duration` {#anise.time.Epoch.duration} + +:rtype: Duration + + +##### Variable `time_scale` {#anise.time.Epoch.time_scale} + +:rtype: TimeScale + #### Methods -##### Method `day_of_year` +##### Method `ceil` {#anise.time.Epoch.ceil} + +> def ceil( +> self, +> /, +> duration +> ) + +Ceils this epoch to the closest provided duration in the TAI time scale + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.ceil(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 18, 0, 0) +); + +// 45 minutes is a multiple of 3 minutes, hence this result +let e = Epoch::from_gregorian_tai(2022, 10, 3, 17, 44, 29, 898032665); +assert_eq!( + e.ceil(3.minutes()), + Epoch::from_gregorian_tai_hms(2022, 10, 3, 17, 45, 0) +); +``` +:type duration: Duration +:rtype: Epoch + + +##### Method `day_of_year` {#anise.time.Epoch.day_of_year} > def day_of_year( > self, @@ -338,9 +448,10 @@ Refer to the appropriate functions for initializing this Epoch from different ti > ) Returns the number of days since the start of the year. +:rtype: float -##### Method `duration_in_year` +##### Method `duration_in_year` {#anise.time.Epoch.duration_in_year} > def duration_in_year( > self, @@ -348,101 +459,138 @@ Returns the number of days since the start of the year. > ) Returns the duration since the start of the year +:rtype: Duration -##### Method `hours` +##### Method `floor` {#anise.time.Epoch.floor} -> def hours( +> def floor( > self, -> / +> /, +> duration > ) -Returns the hours of the Gregorian representation of this epoch in the time scale it was initialized in. +Floors this epoch to the closest provided duration + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.floor(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 0, 0) +); + +let e = Epoch::from_gregorian_tai(2022, 10, 3, 17, 44, 29, 898032665); +assert_eq!( + e.floor(3.minutes()), + Epoch::from_gregorian_tai_hms(2022, 10, 3, 17, 42, 0) +); +``` +:type duration: Duration +:rtype: Epoch -##### Method `init_from_bdt_days` +##### Method `from_bdt_days` {#anise.time.Epoch.from_bdt_days} -> def init_from_bdt_days( +> def from_bdt_days( > days > ) Initialize an Epoch from the number of days since the BeiDou Time Epoch, defined as January 1st 2006 (cf. ). +:type days: float +:rtype: Epoch -##### Method `init_from_bdt_nanoseconds` +##### Method `from_bdt_nanoseconds` {#anise.time.Epoch.from_bdt_nanoseconds} -> def init_from_bdt_nanoseconds( +> def from_bdt_nanoseconds( > nanoseconds > ) Initialize an Epoch from the number of days since the BeiDou Time Epoch, defined as January 1st 2006 (cf. ). This may be useful for time keeping devices that use BDT as a time source. +:type nanoseconds: float +:rtype: Epoch -##### Method `init_from_bdt_seconds` +##### Method `from_bdt_seconds` {#anise.time.Epoch.from_bdt_seconds} -> def init_from_bdt_seconds( +> def from_bdt_seconds( > seconds > ) Initialize an Epoch from the number of seconds since the BeiDou Time Epoch, defined as January 1st 2006 (cf. ). +:type seconds: float +:rtype: Epoch -##### Method `init_from_et_duration` +##### Method `from_et_duration` {#anise.time.Epoch.from_et_duration} -> def init_from_et_duration( +> def from_et_duration( > duration_since_j2000 > ) Initialize an Epoch from the Ephemeris Time duration past 2000 JAN 01 (J2000 reference) +:type duration_since_j2000: Duration +:rtype: Epoch -##### Method `init_from_et_seconds` +##### Method `from_et_seconds` {#anise.time.Epoch.from_et_seconds} -> def init_from_et_seconds( +> def from_et_seconds( > seconds_since_j2000 > ) Initialize an Epoch from the Ephemeris Time seconds past 2000 JAN 01 (J2000 reference) +:type seconds_since_j2000: float +:rtype: Epoch -##### Method `init_from_gpst_days` +##### Method `from_gpst_days` {#anise.time.Epoch.from_gpst_days} -> def init_from_gpst_days( +> def from_gpst_days( > days > ) Initialize an Epoch from the number of days since the GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch -##### Method `init_from_gpst_nanoseconds` +##### Method `from_gpst_nanoseconds` {#anise.time.Epoch.from_gpst_nanoseconds} -> def init_from_gpst_nanoseconds( +> def from_gpst_nanoseconds( > nanoseconds > ) Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). This may be useful for time keeping devices that use GPS as a time source. +:type nanoseconds: float +:rtype: Epoch -##### Method `init_from_gpst_seconds` +##### Method `from_gpst_seconds` {#anise.time.Epoch.from_gpst_seconds} -> def init_from_gpst_seconds( +> def from_gpst_seconds( > seconds > ) Initialize an Epoch from the number of seconds since the GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch -##### Method `init_from_gregorian` +##### Method `from_gregorian` {#anise.time.Epoch.from_gregorian} -> def init_from_gregorian( +> def from_gregorian( > year, > month, > day, @@ -453,30 +601,55 @@ defined as UTC midnight of January 5th to 6th 1980 (cf. time_scale > ) +Initialize from the Gregorian parts +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:type time_scale: TimeScale +:rtype: Epoch + -##### Method `init_from_gregorian_at_midnight` +##### Method `from_gregorian_at_midnight` {#anise.time.Epoch.from_gregorian_at_midnight} -> def init_from_gregorian_at_midnight( +> def from_gregorian_at_midnight( > year, > month, > day, > time_scale > ) +Initialize from the Gregorian parts, time set to midnight +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + -##### Method `init_from_gregorian_at_noon` +##### Method `from_gregorian_at_noon` {#anise.time.Epoch.from_gregorian_at_noon} -> def init_from_gregorian_at_noon( +> def from_gregorian_at_noon( > year, > month, > day, > time_scale > ) +Initialize from the Gregorian parts, time set to noon +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch + -##### Method `init_from_gregorian_tai` +##### Method `from_gregorian_utc` {#anise.time.Epoch.from_gregorian_utc} -> def init_from_gregorian_tai( +> def from_gregorian_utc( > year, > month, > day, @@ -489,472 +662,1222 @@ defined as UTC midnight of January 5th to 6th 1980 (cf. def init_from_gregorian_tai_at_midnight( -> year, -> month, -> day +> def from_gst_days( +> days > ) -Initialize from the Gregorian date at midnight in TAI. +Initialize an Epoch from the number of days since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type days: float +:rtype: Epoch -##### Method `init_from_gregorian_tai_at_noon` +##### Method `from_gst_nanoseconds` {#anise.time.Epoch.from_gst_nanoseconds} -> def init_from_gregorian_tai_at_noon( -> year, -> month, -> day +> def from_gst_nanoseconds( +> nanoseconds > ) -Initialize from the Gregorian date at noon in TAI +Initialize an Epoch from the number of nanoseconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +This may be useful for time keeping devices that use GST as a time source. +:type nanoseconds: float +:rtype: Epoch -##### Method `init_from_gregorian_tai_hms` +##### Method `from_gst_seconds` {#anise.time.Epoch.from_gst_seconds} -> def init_from_gregorian_tai_hms( -> year, -> month, -> day, -> hour, -> minute, -> second +> def from_gst_seconds( +> seconds > ) -Initialize from the Gregorian date and time (without the nanoseconds) in TAI +Initialize an Epoch from the number of seconds since the Galileo Time Epoch, +starting on August 21st 1999 Midnight UT, +(cf. ). +:type seconds: float +:rtype: Epoch -##### Method `init_from_gregorian_utc` +##### Method `from_jde_et` {#anise.time.Epoch.from_jde_et} -> def init_from_gregorian_utc( +> def from_jde_et( +> days +> ) + +Initialize from the JDE days +:type days: float +:rtype: Epoch + + +##### Method `from_jde_tai` {#anise.time.Epoch.from_jde_tai} + +> def from_jde_tai( +> days +> ) + +Initialize an Epoch from given JDE in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `from_jde_tdb` {#anise.time.Epoch.from_jde_tdb} + +> def from_jde_tdb( +> days +> ) + +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) in JD days +:type days: float +:rtype: Epoch + + +##### Method `from_jde_utc` {#anise.time.Epoch.from_jde_utc} + +> def from_jde_utc( +> days +> ) + +Initialize an Epoch from given JDE in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `from_mjd_tai` {#anise.time.Epoch.from_mjd_tai} + +> def from_mjd_tai( +> days +> ) + +Initialize an Epoch from given MJD in TAI time scale +:type days: float +:rtype: Epoch + + +##### Method `from_mjd_utc` {#anise.time.Epoch.from_mjd_utc} + +> def from_mjd_utc( +> days +> ) + +Initialize an Epoch from given MJD in UTC time scale +:type days: float +:rtype: Epoch + + +##### Method `from_ptp_duration` {#anise.time.Epoch.from_ptp_duration} + +> def from_ptp_duration( +> duration +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) duration since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type duration: Duration +:rtype: Epoch + + +##### Method `from_ptp_nanoseconds` {#anise.time.Epoch.from_ptp_nanoseconds} + +> def from_ptp_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) nanoseconds timestamp since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_ptp_seconds` {#anise.time.Epoch.from_ptp_seconds} + +> def from_ptp_seconds( +> seconds +> ) + +Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) second timestamp since TAI midnight 1970 January 01. +PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. + +:type seconds: float +:rtype: Epoch + + +##### Method `from_qzsst_days` {#anise.time.Epoch.from_qzsst_days} + +> def from_qzsst_days( +> days +> ) + +Initialize an Epoch from the number of days since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `from_qzsst_nanoseconds` {#anise.time.Epoch.from_qzsst_nanoseconds} + +> def from_qzsst_nanoseconds( +> nanoseconds +> ) + +Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use QZSS as a time source. +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_qzsst_seconds` {#anise.time.Epoch.from_qzsst_seconds} + +> def from_qzsst_seconds( +> seconds +> ) + +Initialize an Epoch from the number of seconds since the QZSS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `from_tai_days` {#anise.time.Epoch.from_tai_days} + +> def from_tai_days( +> days +> ) + +Initialize an Epoch from the provided TAI days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `from_tai_duration` {#anise.time.Epoch.from_tai_duration} + +> def from_tai_duration( +> duration +> ) + +Creates a new Epoch from a Duration as the time difference between this epoch and TAI reference epoch. +:type duration: Duration +:rtype: Epoch + + +##### Method `from_tai_parts` {#anise.time.Epoch.from_tai_parts} + +> def from_tai_parts( +> centuries, +> nanoseconds +> ) + +Creates a new Epoch from its centuries and nanosecond since the TAI reference epoch. +:type centuries: int +:type nanoseconds: int +:rtype: Epoch + + +##### Method `from_tai_seconds` {#anise.time.Epoch.from_tai_seconds} + +> def from_tai_seconds( +> seconds +> ) + +Initialize an Epoch from the provided TAI seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `from_tdb_duration` {#anise.time.Epoch.from_tdb_duration} + +> def from_tdb_duration( +> duration_since_j2000 +> ) + +Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI. + :type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `from_tdb_seconds` {#anise.time.Epoch.from_tdb_seconds} + +> def from_tdb_seconds( +> seconds_j2000 +> ) + +Initialize an Epoch from Dynamic Barycentric Time (TDB) seconds past 2000 JAN 01 midnight (difference than SPICE) +NOTE: This uses the ESA algorithm, which is a notch more complicated than the SPICE algorithm, but more precise. +In fact, SPICE algorithm is precise +/- 30 microseconds for a century whereas ESA algorithm should be exactly correct. +:type seconds_j2000: float +:rtype: Epoch + + +##### Method `from_tt_duration` {#anise.time.Epoch.from_tt_duration} + +> def from_tt_duration( +> duration +> ) + +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type duration: Duration +:rtype: Epoch + + +##### Method `from_tt_seconds` {#anise.time.Epoch.from_tt_seconds} + +> def from_tt_seconds( +> seconds +> ) + +Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type seconds: float +:rtype: Epoch + + +##### Method `from_unix_milliseconds` {#anise.time.Epoch.from_unix_milliseconds} + +> def from_unix_milliseconds( +> milliseconds +> ) + +Initialize an Epoch from the provided UNIX millisecond timestamp since UTC midnight 1970 January 01. +:type milliseconds: float +:rtype: Epoch + + +##### Method `from_unix_seconds` {#anise.time.Epoch.from_unix_seconds} + +> def from_unix_seconds( +> seconds +> ) + +Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1970 January 01. +:type seconds: float +:rtype: Epoch + + +##### Method `from_utc_days` {#anise.time.Epoch.from_utc_days} + +> def from_utc_days( +> days +> ) + +Initialize an Epoch from the provided UTC days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch + + +##### Method `from_utc_seconds` {#anise.time.Epoch.from_utc_seconds} + +> def from_utc_seconds( +> seconds +> ) + +Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `fromdatetime` {#anise.time.Epoch.fromdatetime} + +> def fromdatetime( +> dt +> ) + +Builds an Epoch in UTC from the provided datetime after timezone correction if any is present. +:type dt: datetime.datetime +:rtype: Epoch + + +##### Method `hours` {#anise.time.Epoch.hours} + +> def hours( +> self, +> / +> ) + +Returns the hours of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `init_from_bdt_days` {#anise.time.Epoch.init_from_bdt_days} + +> def init_from_bdt_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_days instead +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_bdt_nanoseconds` {#anise.time.Epoch.init_from_bdt_nanoseconds} + +> def init_from_bdt_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_nanoseconds instead +Initialize an Epoch from the number of days since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +This may be useful for time keeping devices that use BDT as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `init_from_bdt_seconds` {#anise.time.Epoch.init_from_bdt_seconds} + +> def init_from_bdt_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_bdt\_seconds instead +Initialize an Epoch from the number of seconds since the BeiDou Time Epoch, +defined as January 1st 2006 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_et_duration` {#anise.time.Epoch.init_from_et_duration} + +> def init_from_et_duration( +> duration_since_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_et\_duration instead +Initialize an Epoch from the Ephemeris Time duration past 2000 JAN 01 (J2000 reference) +:type duration_since_j2000: Duration +:rtype: Epoch + + +##### Method `init_from_et_seconds` {#anise.time.Epoch.init_from_et_seconds} + +> def init_from_et_seconds( +> seconds_since_j2000 +> ) + +WARNING: Deprecated since 4.1.1; Use from\_et\_seconds instead +Initialize an Epoch from the Ephemeris Time seconds past 2000 JAN 01 (J2000 reference) +:type seconds_since_j2000: float +:rtype: Epoch + + +##### Method `init_from_gpst_days` {#anise.time.Epoch.init_from_gpst_days} + +> def init_from_gpst_days( +> days +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_days instead +Initialize an Epoch from the number of days since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch + + +##### Method `init_from_gpst_nanoseconds` {#anise.time.Epoch.init_from_gpst_nanoseconds} + +> def init_from_gpst_nanoseconds( +> nanoseconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_nanoseconds instead +Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +This may be useful for time keeping devices that use GPS as a time source. +:type nanoseconds: float +:rtype: Epoch + + +##### Method `init_from_gpst_seconds` {#anise.time.Epoch.init_from_gpst_seconds} + +> def init_from_gpst_seconds( +> seconds +> ) + +WARNING: Deprecated since 4.1.1; Use from\_gpst\_seconds instead +Initialize an Epoch from the number of seconds since the GPS Time Epoch, +defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch + + +##### Method `init_from_gregorian` {#anise.time.Epoch.init_from_gregorian} + +> def init_from_gregorian( > year, > month, > day, > hour, > minute, > second, -> nanos +> nanos, +> time_scale > ) -Builds an Epoch from the provided Gregorian date and time in TAI. If invalid date is provided, this function will panic. -Use maybe_from_gregorian_tai if unsure. +WARNING: Deprecated since 4.1.1; Use from\_gregorian instead +Initialize from the Gregorian parts +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:type time_scale: TimeScale +:rtype: Epoch -##### Method `init_from_gregorian_utc_at_midnight` +##### Method `init_from_gregorian_at_midnight` {#anise.time.Epoch.init_from_gregorian_at_midnight} -> def init_from_gregorian_utc_at_midnight( +> def init_from_gregorian_at_midnight( > year, > month, -> day +> day, +> time_scale > ) -Initialize from Gregorian date in UTC at midnight +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_at\_midnight instead +Initialize from the Gregorian parts, time set to midnight +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch -##### Method `init_from_gregorian_utc_at_noon` +##### Method `init_from_gregorian_at_noon` {#anise.time.Epoch.init_from_gregorian_at_noon} -> def init_from_gregorian_utc_at_noon( +> def init_from_gregorian_at_noon( > year, > month, -> day +> day, +> time_scale > ) -Initialize from Gregorian date in UTC at noon +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_at\_noon instead +Initialize from the Gregorian parts, time set to noon +:type year: int +:type month: int +:type day: int +:type time_scale: TimeScale +:rtype: Epoch -##### Method `init_from_gregorian_utc_hms` +##### Method `init_from_gregorian_utc` {#anise.time.Epoch.init_from_gregorian_utc} -> def init_from_gregorian_utc_hms( +> def init_from_gregorian_utc( > year, > month, > day, > hour, > minute, -> second +> second, +> nanos > ) -Initialize from the Gregorian date and time (without the nanoseconds) in UTC +WARNING: Deprecated since 4.1.1; Use from\_gregorian\_utc instead +Builds an Epoch from the provided Gregorian date and time in TAI. If invalid date is provided, this function will panic. +Use maybe_from_gregorian_tai if unsure. + +:type year: int +:type month: int +:type day: int +:type hour: int +:type minute: int +:type second: int +:type nanos: int +:rtype: Epoch -##### Method `init_from_gst_days` +##### Method `init_from_gst_days` {#anise.time.Epoch.init_from_gst_days} > def init_from_gst_days( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_gst\_days instead Initialize an Epoch from the number of days since the Galileo Time Epoch, starting on August 21st 1999 Midnight UT, (cf. ). +:type days: float +:rtype: Epoch -##### Method `init_from_gst_nanoseconds` +##### Method `init_from_gst_nanoseconds` {#anise.time.Epoch.init_from_gst_nanoseconds} > def init_from_gst_nanoseconds( > nanoseconds > ) +WARNING: Deprecated since 4.1.1; Use from\_gst\_nanoseconds instead Initialize an Epoch from the number of nanoseconds since the Galileo Time Epoch, starting on August 21st 1999 Midnight UT, (cf. ). This may be useful for time keeping devices that use GST as a time source. +:type nanoseconds: float +:rtype: Epoch -##### Method `init_from_gst_seconds` +##### Method `init_from_gst_seconds` {#anise.time.Epoch.init_from_gst_seconds} > def init_from_gst_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_gst\_seconds instead Initialize an Epoch from the number of seconds since the Galileo Time Epoch, starting on August 21st 1999 Midnight UT, (cf. ). +:type seconds: float +:rtype: Epoch -##### Method `init_from_jde_et` +##### Method `init_from_jde_et` {#anise.time.Epoch.init_from_jde_et} > def init_from_jde_et( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_jde\_et instead Initialize from the JDE days +:type days: float +:rtype: Epoch -##### Method `init_from_jde_tai` +##### Method `init_from_jde_tai` {#anise.time.Epoch.init_from_jde_tai} > def init_from_jde_tai( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_jde\_tai instead Initialize an Epoch from given JDE in TAI time scale +:type days: float +:rtype: Epoch -##### Method `init_from_jde_tdb` +##### Method `init_from_jde_tdb` {#anise.time.Epoch.init_from_jde_tdb} > def init_from_jde_tdb( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_jde\_tdb instead Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) in JD days +:type days: float +:rtype: Epoch -##### Method `init_from_jde_utc` +##### Method `init_from_jde_utc` {#anise.time.Epoch.init_from_jde_utc} > def init_from_jde_utc( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_jde\_utc instead Initialize an Epoch from given JDE in UTC time scale +:type days: float +:rtype: Epoch -##### Method `init_from_mjd_tai` +##### Method `init_from_mjd_tai` {#anise.time.Epoch.init_from_mjd_tai} > def init_from_mjd_tai( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_mjd\_tai instead Initialize an Epoch from given MJD in TAI time scale +:type days: float +:rtype: Epoch -##### Method `init_from_mjd_utc` +##### Method `init_from_mjd_utc` {#anise.time.Epoch.init_from_mjd_utc} > def init_from_mjd_utc( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_mjd\_utc instead Initialize an Epoch from given MJD in UTC time scale +:type days: float +:rtype: Epoch -##### Method `init_from_qzsst_days` +##### Method `init_from_qzsst_days` {#anise.time.Epoch.init_from_qzsst_days} > def init_from_qzsst_days( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_days instead Initialize an Epoch from the number of days since the QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type days: float +:rtype: Epoch -##### Method `init_from_qzsst_nanoseconds` +##### Method `init_from_qzsst_nanoseconds` {#anise.time.Epoch.init_from_qzsst_nanoseconds} > def init_from_qzsst_nanoseconds( > nanoseconds > ) +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_nanoseconds instead Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). This may be useful for time keeping devices that use QZSS as a time source. +:type nanoseconds: int +:rtype: Epoch -##### Method `init_from_qzsst_seconds` +##### Method `init_from_qzsst_seconds` {#anise.time.Epoch.init_from_qzsst_seconds} > def init_from_qzsst_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_qzsst\_seconds instead Initialize an Epoch from the number of seconds since the QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:type seconds: float +:rtype: Epoch -##### Method `init_from_tai_days` +##### Method `init_from_tai_days` {#anise.time.Epoch.init_from_tai_days} > def init_from_tai_days( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_tai\_days instead Initialize an Epoch from the provided TAI days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch -##### Method `init_from_tai_duration` +##### Method `init_from_tai_duration` {#anise.time.Epoch.init_from_tai_duration} > def init_from_tai_duration( > duration > ) +WARNING: Deprecated since 4.1.1; Use from\_tai\_duration instead Creates a new Epoch from a Duration as the time difference between this epoch and TAI reference epoch. +:type duration: Duration +:rtype: Epoch -##### Method `init_from_tai_parts` +##### Method `init_from_tai_parts` {#anise.time.Epoch.init_from_tai_parts} > def init_from_tai_parts( > centuries, > nanoseconds > ) +WARNING: Deprecated since 4.1.1; Use from\_tai\_parts instead Creates a new Epoch from its centuries and nanosecond since the TAI reference epoch. +:type centuries: int +:type nanoseconds: int +:rtype: Epoch -##### Method `init_from_tai_seconds` +##### Method `init_from_tai_seconds` {#anise.time.Epoch.init_from_tai_seconds} > def init_from_tai_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_tai\_seconds instead Initialize an Epoch from the provided TAI seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch -##### Method `init_from_tdb_duration` +##### Method `init_from_tdb_duration` {#anise.time.Epoch.init_from_tdb_duration} > def init_from_tdb_duration( > duration_since_j2000 > ) +WARNING: Deprecated since 4.1.1; Use from\_tdb\_duration instead Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI. + :type duration_since_j2000: Duration +:rtype: Epoch -##### Method `init_from_tdb_seconds` +##### Method `init_from_tdb_seconds` {#anise.time.Epoch.init_from_tdb_seconds} > def init_from_tdb_seconds( > seconds_j2000 > ) +WARNING: Deprecated since 4.1.1; Use from\_tdb\_seconds instead Initialize an Epoch from Dynamic Barycentric Time (TDB) seconds past 2000 JAN 01 midnight (difference than SPICE) NOTE: This uses the ESA algorithm, which is a notch more complicated than the SPICE algorithm, but more precise. In fact, SPICE algorithm is precise +/- 30 microseconds for a century whereas ESA algorithm should be exactly correct. +:type seconds_j2000: float +:rtype: Epoch -##### Method `init_from_tt_duration` +##### Method `init_from_tt_duration` {#anise.time.Epoch.init_from_tt_duration} > def init_from_tt_duration( > duration > ) +WARNING: Deprecated since 4.1.1; Use from\_tt\_duration instead Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type duration: Duration +:rtype: Epoch -##### Method `init_from_tt_seconds` +##### Method `init_from_tt_seconds` {#anise.time.Epoch.init_from_tt_seconds} > def init_from_tt_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_tt\_seconds instead Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) +:type seconds: float +:rtype: Epoch -##### Method `init_from_unix_milliseconds` +##### Method `init_from_unix_milliseconds` {#anise.time.Epoch.init_from_unix_milliseconds} > def init_from_unix_milliseconds( > milliseconds > ) +WARNING: Deprecated since 4.1.1; Use from\_unix\_milliseconds instead Initialize an Epoch from the provided UNIX millisecond timestamp since UTC midnight 1970 January 01. +:type milliseconds: float +:rtype: Epoch -##### Method `init_from_unix_seconds` +##### Method `init_from_unix_seconds` {#anise.time.Epoch.init_from_unix_seconds} > def init_from_unix_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_unix\_seconds instead Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1970 January 01. +:type seconds: float +:rtype: Epoch -##### Method `init_from_utc_days` +##### Method `init_from_utc_days` {#anise.time.Epoch.init_from_utc_days} > def init_from_utc_days( > days > ) +WARNING: Deprecated since 4.1.1; Use from\_utc\_days instead Initialize an Epoch from the provided UTC days since 1900 January 01 at midnight +:type days: float +:rtype: Epoch -##### Method `init_from_utc_seconds` +##### Method `init_from_utc_seconds` {#anise.time.Epoch.init_from_utc_seconds} > def init_from_utc_seconds( > seconds > ) +WARNING: Deprecated since 4.1.1; Use from\_utc\_seconds instead Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight +:type seconds: float +:rtype: Epoch + + +##### Method `isoformat` {#anise.time.Epoch.isoformat} + +> def isoformat( +> self, +> / +> ) + +Equivalent to datetime.isoformat, and truncated to 23 chars, refer to for format options +:rtype: str + + +##### Method `leap_seconds` {#anise.time.Epoch.leap_seconds} + +> def leap_seconds( +> self, +> /, +> iers_only +> ) + +Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds and the SOFA scaling from 1960 to 1972, depending on flag. +Returns None if the epoch is before 1960, year at which UTC was defined. + +##### Why does this function return an Option when the other returns a value +This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. +:type iers_only: bool +:rtype: float + + +##### Method `leap_seconds_iers` {#anise.time.Epoch.leap_seconds_iers} + +> def leap_seconds_iers( +> self, +> / +> ) + +Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds. +:rtype: int + + +##### Method `leap_seconds_with_file` {#anise.time.Epoch.leap_seconds_with_file} + +> def leap_seconds_with_file( +> self, +> /, +> iers_only, +> provider +> ) + +Get the accumulated number of leap seconds up to this Epoch from the provided LeapSecondProvider. +Returns None if the epoch is before 1960, year at which UTC was defined. + +##### Why does this function return an Option when the other returns a value +This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. + +:type iers_only: bool +:type provider: LeapSecondsFile +:rtype: float + + +##### Method `max` {#anise.time.Epoch.max} + +> def max( +> self, +> /, +> other +> ) + +Returns the maximum of the two epochs. + +``` +use hifitime::Epoch; + +let e0 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 20); +let e1 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 21); + +assert_eq!(e1, e1.max(e0)); +assert_eq!(e1, e0.max(e1)); +``` + +_Note:_ this uses a pointer to self which will be copied immediately because Python requires a pointer. +:type other: Epoch +:rtype: Epoch + + +##### Method `microseconds` {#anise.time.Epoch.microseconds} + +> def microseconds( +> self, +> / +> ) + +Returns the microseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `milliseconds` {#anise.time.Epoch.milliseconds} + +> def milliseconds( +> self, +> / +> ) + +Returns the milliseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `min` {#anise.time.Epoch.min} + +> def min( +> self, +> /, +> other +> ) + +Returns the minimum of the two epochs. + +``` +use hifitime::Epoch; + +let e0 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 20); +let e1 = Epoch::from_gregorian_utc_at_midnight(2022, 10, 21); + +assert_eq!(e0, e1.min(e0)); +assert_eq!(e0, e0.min(e1)); +``` + +_Note:_ this uses a pointer to self which will be copied immediately because Python requires a pointer. +:type other: Epoch +:rtype: Epoch + + +##### Method `minutes` {#anise.time.Epoch.minutes} + +> def minutes( +> self, +> / +> ) + +Returns the minutes of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int + + +##### Method `month_name` {#anise.time.Epoch.month_name} + +> def month_name( +> self, +> / +> ) + +:rtype: MonthName -##### Method `isoformat` +##### Method `nanoseconds` {#anise.time.Epoch.nanoseconds} -> def isoformat( +> def nanoseconds( > self, > / > ) -Equivalent to datetime.isoformat, and truncated to 23 chars, refer to for format options +Returns the nanoseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int -##### Method `leap_seconds` +##### Method `next` {#anise.time.Epoch.next} -> def leap_seconds( +> def next( > self, > /, -> iers_only +> weekday > ) -Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds and the SOFA scaling from 1960 to 1972, depending on flag. -Returns None if the epoch is before 1960, year at which UTC was defined. +Returns the next weekday. -##### Why does this function return an Option when the other returns a value -This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. +``` +use hifitime::prelude::*; + +let epoch = Epoch::from_gregorian_utc_at_midnight(1988, 1, 2); +assert_eq!(epoch.weekday_utc(), Weekday::Saturday); +assert_eq!(epoch.next(Weekday::Sunday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 3)); +assert_eq!(epoch.next(Weekday::Monday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 4)); +assert_eq!(epoch.next(Weekday::Tuesday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 5)); +assert_eq!(epoch.next(Weekday::Wednesday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 6)); +assert_eq!(epoch.next(Weekday::Thursday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 7)); +assert_eq!(epoch.next(Weekday::Friday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 8)); +assert_eq!(epoch.next(Weekday::Saturday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 9)); +``` +:type weekday: Weekday +:rtype: Epoch -##### Method `leap_seconds_iers` +##### Method `next_weekday_at_midnight` {#anise.time.Epoch.next_weekday_at_midnight} -> def leap_seconds_iers( +> def next_weekday_at_midnight( > self, -> / +> /, +> weekday > ) -Get the accumulated number of leap seconds up to this Epoch accounting only for the IERS leap seconds. +:type weekday: Weekday +:rtype: Epoch -##### Method `leap_seconds_with_file` +##### Method `next_weekday_at_noon` {#anise.time.Epoch.next_weekday_at_noon} -> def leap_seconds_with_file( +> def next_weekday_at_noon( > self, > /, -> iers_only, -> provider +> weekday > ) -Get the accumulated number of leap seconds up to this Epoch from the provided LeapSecondProvider. -Returns None if the epoch is before 1960, year at which UTC was defined. - -##### Why does this function return an Option when the other returns a value -This is to match the iauDat function of SOFA (src/dat.c). That function will return a warning and give up if the start date is before 1960. +:type weekday: Weekday +:rtype: Epoch -##### Method `maybe_init_from_gregorian` +##### Method `precise_timescale_conversion` {#anise.time.Epoch.precise_timescale_conversion} -> def maybe_init_from_gregorian( -> year, -> month, -> day, -> hour, -> minute, -> second, -> nanos, -> time_scale +> def precise_timescale_conversion( +> self, +> /, +> forward, +> reference_epoch, +> polynomial, +> target > ) -Attempts to build an Epoch from the provided Gregorian date and time in the provided time scale. -NOTE: If the time scale is TDB, this function assumes that the SPICE format is used +Converts this [Epoch] into targeted [TimeScale] using provided [Polynomial]. - -##### Method `maybe_init_from_gregorian_tai` +###### Input +- forward: whether this is forward or backward conversion. + For example, using GPST-UTC [Polynomial] + - GPST->UTC is the forward conversion + - UTC->GPST is the backward conversion +- reference_epoch: any reference [Epoch] for the provided [Polynomial]. -> def maybe_init_from_gregorian_tai( -> year, -> month, -> day, -> hour, -> minute, -> second, -> nanos -> ) +While we support any time difference, it should remain short in pratice (a day at most, for precise applications). +- polynomial: that must be valid for this reference [Epoch], used in the equation `a0 + a1*dt + a2*dt² = GPST-UTC` for example. +- target: targetted [TimeScale] we will transition to. -Attempts to build an Epoch from the provided Gregorian date and time in TAI. +Example: +``` +use hifitime::{Epoch, TimeScale, Polynomial, Unit}; - -##### Method `maybe_init_from_gregorian_utc` +// random GPST Epoch for forward conversion to UTC +let t_gpst = Epoch::from_gregorian(2020, 01, 01, 0, 0, 0, 0, TimeScale::GPST); -> def maybe_init_from_gregorian_utc( -> year, -> month, -> day, -> hour, -> minute, -> second, -> nanos -> ) +// Let's say we know the GPST-UTC polynomials for that day, +// They allow precise forward transition from GPST to UTC, +// and precise backward transition from UTC to GPST. +let gpst_utc_polynomials = Polynomial::from_constant_offset_nanoseconds(1.0); -Attempts to build an Epoch from the provided Gregorian date and time in UTC. +// This is the reference [Epoch] attached to the publication of these polynomials. +// You should use polynomials that remain valid and were provided recently (usually one day at most). +// Example: polynomials were published 1 hour ago. +let gpst_reference = t_gpst - 1.0 * Unit::Hour; - -##### Method `microseconds` +// Forward conversion (to UTC) GPST - a0 + a1 *dt + a2*dt² = UTC +let t_utc = t_gpst.precise_timescale_conversion(true, gpst_reference, gpst_utc_polynomials, TimeScale::UTC) + .unwrap(); -> def microseconds( -> self, -> / -> ) +// Verify we did transition to UTC +assert_eq!(t_utc.time_scale, TimeScale::UTC); -Returns the microseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +// Verify the resulting [Epoch] is the coarse GPST->UTC transition + fine correction +let reversed = t_utc.to_time_scale(TimeScale::GPST) + 1.0 * Unit::Nanosecond; +assert_eq!(reversed, t_gpst); + +// Apply the backward transition, from t_utc back to t_gpst. +// The timescale conversion works both ways: (from UTC) GPST = UTC + a0 + a1 *dt + a2*dt² +let backwards = t_utc.precise_timescale_conversion(false, gpst_reference, gpst_utc_polynomials, TimeScale::GPST) + .unwrap(); + +assert_eq!(backwards, t_gpst); + +// It is important to understand that your reference point does not have to be in the past. +// The only logic that should prevail is to always minimize interpolation gap. +// In other words, if you can access future interpolation information that would minimize the data gap, they should prevail. +// Example: +30' in the future. +let gpst_reference = t_gpst + 30.0 * Unit::Minute; + +// Forward conversion (to UTC) but using polynomials that were released 1 hour after t_gpst +let t_utc = t_gpst.precise_timescale_conversion(true, gpst_reference, gpst_utc_polynomials, TimeScale::UTC) + .unwrap(); + +// Verifications +assert_eq!(t_utc.time_scale, TimeScale::UTC); + +let reversed = t_utc.to_time_scale(TimeScale::GPST) + 1.0 * Unit::Nanosecond; +assert_eq!(reversed, t_gpst); +``` +:type forward: bool +:type reference_epoch: Epoch +:type polynomial: Polynomial +:type target: TimeScale +:rtype: Epoch -##### Method `milliseconds` +##### Method `previous` {#anise.time.Epoch.previous} -> def milliseconds( +> def previous( > self, -> / +> /, +> weekday > ) -Returns the milliseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +Returns the next weekday. + +``` +use hifitime::prelude::*; + +let epoch = Epoch::from_gregorian_utc_at_midnight(1988, 1, 2); +assert_eq!(epoch.previous(Weekday::Friday), Epoch::from_gregorian_utc_at_midnight(1988, 1, 1)); +assert_eq!(epoch.previous(Weekday::Thursday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 31)); +assert_eq!(epoch.previous(Weekday::Wednesday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 30)); +assert_eq!(epoch.previous(Weekday::Tuesday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 29)); +assert_eq!(epoch.previous(Weekday::Monday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 28)); +assert_eq!(epoch.previous(Weekday::Sunday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 27)); +assert_eq!(epoch.previous(Weekday::Saturday), Epoch::from_gregorian_utc_at_midnight(1987, 12, 26)); +``` +:type weekday: Weekday +:rtype: Epoch -##### Method `minutes` +##### Method `previous_weekday_at_midnight` {#anise.time.Epoch.previous_weekday_at_midnight} -> def minutes( +> def previous_weekday_at_midnight( > self, -> / +> /, +> weekday > ) -Returns the minutes of the Gregorian representation of this epoch in the time scale it was initialized in. +:type weekday: Weekday +:rtype: Epoch -##### Method `month_name` +##### Method `previous_weekday_at_noon` {#anise.time.Epoch.previous_weekday_at_noon} -> def month_name( +> def previous_weekday_at_noon( > self, -> / +> /, +> weekday > ) +:type weekday: Weekday +:rtype: Epoch + -##### Method `nanoseconds` +##### Method `round` {#anise.time.Epoch.round} -> def nanoseconds( +> def round( > self, -> / +> /, +> duration > ) -Returns the nanoseconds of the Gregorian representation of this epoch in the time scale it was initialized in. +Rounds this epoch to the closest provided duration in TAI + +##### Example +``` +use hifitime::{Epoch, TimeUnits}; + +let e = Epoch::from_gregorian_tai_hms(2022, 5, 20, 17, 57, 43); +assert_eq!( + e.round(1.hours()), + Epoch::from_gregorian_tai_hms(2022, 5, 20, 18, 0, 0) +); +``` +:type duration: Duration +:rtype: Epoch -##### Method `seconds` +##### Method `seconds` {#anise.time.Epoch.seconds} > def seconds( > self, @@ -962,9 +1885,10 @@ Returns the nanoseconds of the Gregorian representation of this epoch in the ti > ) Returns the seconds of the Gregorian representation of this epoch in the time scale it was initialized in. +:rtype: int -##### Method `strftime` +##### Method `strftime` {#anise.time.Epoch.strftime} > def strftime( > self, @@ -972,10 +1896,12 @@ Returns the seconds of the Gregorian representation of this epoch in the time s > format_str > ) -Equivalent to datetime.strftime, refer to for format options +Formats the epoch according to the given format string. Supports a subset of C89 and hifitime-specific format codes. Refer to for available format options. +:type format_str: str +:rtype: str -##### Method `strptime` +##### Method `strptime` {#anise.time.Epoch.strptime} > def strptime( > epoch_str, @@ -983,14 +1909,21 @@ Equivalent to datetime.strftime, refer to ) Equivalent to datetime.strptime, refer to for format options +:type epoch_str: str +:type format_str: str +:rtype: Epoch -##### Method `system_now` +##### Method `system_now` {#anise.time.Epoch.system_now} > def system_now() +Returns the computer clock in UTC + +:rtype: Epoch + -##### Method `timedelta` +##### Method `timedelta` {#anise.time.Epoch.timedelta} > def timedelta( > self, @@ -998,8 +1931,12 @@ Equivalent to datetime.strptime, refer to other > ) +Differences between two epochs +:type other: Duration +:rtype: Duration + -##### Method `to_bdt_days` +##### Method `to_bdt_days` {#anise.time.Epoch.to_bdt_days} > def to_bdt_days( > self, @@ -1008,19 +1945,21 @@ Equivalent to datetime.strptime, refer to ). +:rtype: float -##### Method `to_bdt_duration` +##### Method `to_bdt_duration` {#anise.time.Epoch.to_bdt_duration} > def to_bdt_duration( > self, > / > ) -Returns [Duration](#time.Duration "time.Duration") past BDT (BeiDou) time Epoch. +Returns [Duration](#anise.time.Duration "anise.time.Duration") past BDT (BeiDou) time Epoch. +:rtype: Duration -##### Method `to_bdt_nanoseconds` +##### Method `to_bdt_nanoseconds` {#anise.time.Epoch.to_bdt_nanoseconds} > def to_bdt_nanoseconds( > self, @@ -1030,9 +1969,10 @@ Returns [Duration](#time.Duration "time.Duration") past BDT (BeiDou Returns nanoseconds past BDT (BeiDou) Time Epoch, defined as Jan 01 2006 UTC (cf. ). NOTE: This function will return an error if the centuries past GST time are not zero. +:rtype: int -##### Method `to_bdt_seconds` +##### Method `to_bdt_seconds` {#anise.time.Epoch.to_bdt_seconds} > def to_bdt_seconds( > self, @@ -1040,9 +1980,10 @@ NOTE: This function will return an error if the centuries past GST time are not > ) Returns seconds past BDT (BeiDou) Time Epoch +:rtype: float -##### Method `to_duration_in_time_scale` +##### Method `to_duration_in_time_scale` {#anise.time.Epoch.to_duration_in_time_scale} > def to_duration_in_time_scale( > self, @@ -1052,9 +1993,11 @@ Returns seconds past BDT (BeiDou) Time Epoch Returns this epoch with respect to the provided time scale. This is needed to correctly perform duration conversions in dynamical time scales (e.g. TDB). +:type ts: TimeScale +:rtype: Duration -##### Method `to_et_centuries_since_j2000` +##### Method `to_et_centuries_since_j2000` {#anise.time.Epoch.to_et_centuries_since_j2000} > def to_et_centuries_since_j2000( > self, @@ -1062,9 +2005,10 @@ This is needed to correctly perform duration conversions in dynamical time scale > ) Returns the number of centuries since Ephemeris Time (ET) J2000 (used for Archinal et al. rotations) +:rtype: float -##### Method `to_et_days_since_j2000` +##### Method `to_et_days_since_j2000` {#anise.time.Epoch.to_et_days_since_j2000} > def to_et_days_since_j2000( > self, @@ -1072,9 +2016,10 @@ Returns the number of centuries since Ephemeris Time (ET) J2000 (used for Archin > ) Returns the number of days since Ephemeris Time (ET) J2000 (used for Archinal et al. rotations) +:rtype: float -##### Method `to_et_duration` +##### Method `to_et_duration` {#anise.time.Epoch.to_et_duration} > def to_et_duration( > self, @@ -1089,9 +2034,10 @@ as this date introduces 10 leap seconds. At the time of writing, this does _not_ line with IERS and the documentation in the leap seconds list. In order to match SPICE, the as_et_duration() function will manually get rid of that difference. +:rtype: Duration -##### Method `to_et_seconds` +##### Method `to_et_seconds` {#anise.time.Epoch.to_et_seconds} > def to_et_seconds( > self, @@ -1099,9 +2045,10 @@ In order to match SPICE, the as_et_duration() function will manually get rid of > ) Returns the Ephemeris Time seconds past 2000 JAN 01 midnight, matches NASA/NAIF SPICE. +:rtype: float -##### Method `to_gpst_days` +##### Method `to_gpst_days` {#anise.time.Epoch.to_gpst_days} > def to_gpst_days( > self, @@ -1109,19 +2056,21 @@ Returns the Ephemeris Time seconds past 2000 JAN 01 midnight, matches NASA/NAIF > ) Returns days past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float -##### Method `to_gpst_duration` +##### Method `to_gpst_duration` {#anise.time.Epoch.to_gpst_duration} > def to_gpst_duration( > self, > / > ) -Returns [Duration](#time.Duration "time.Duration") past GPS time Epoch. +Returns [Duration](#anise.time.Duration "anise.time.Duration") past GPS time Epoch. +:rtype: Duration -##### Method `to_gpst_nanoseconds` +##### Method `to_gpst_nanoseconds` {#anise.time.Epoch.to_gpst_nanoseconds} > def to_gpst_nanoseconds( > self, @@ -1130,9 +2079,10 @@ Returns [Duration](#time.Duration "time.Duration") past GPS time Ep Returns nanoseconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). NOTE: This function will return an error if the centuries past GPST time are not zero. +:rtype: int -##### Method `to_gpst_seconds` +##### Method `to_gpst_seconds` {#anise.time.Epoch.to_gpst_seconds} > def to_gpst_seconds( > self, @@ -1140,9 +2090,10 @@ NOTE: This function will return an error if the centuries past GPST time are not > ) Returns seconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float -##### Method `to_gst_days` +##### Method `to_gst_days` {#anise.time.Epoch.to_gst_days} > def to_gst_days( > self, @@ -1152,19 +2103,21 @@ Returns seconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6 Returns days past GST (Galileo) Time Epoch, starting on August 21st 1999 Midnight UT (cf. ). +:rtype: float -##### Method `to_gst_duration` +##### Method `to_gst_duration` {#anise.time.Epoch.to_gst_duration} > def to_gst_duration( > self, > / > ) -Returns [Duration](#time.Duration "time.Duration") past GST (Galileo) time Epoch. +Returns [Duration](#anise.time.Duration "anise.time.Duration") past GST (Galileo) time Epoch. +:rtype: Duration -##### Method `to_gst_nanoseconds` +##### Method `to_gst_nanoseconds` {#anise.time.Epoch.to_gst_nanoseconds} > def to_gst_nanoseconds( > self, @@ -1174,9 +2127,10 @@ Returns [Duration](#time.Duration "time.Duration") past GST (Galile Returns nanoseconds past GST (Galileo) Time Epoch, starting on August 21st 1999 Midnight UT (cf. ). NOTE: This function will return an error if the centuries past GST time are not zero. +:rtype: int -##### Method `to_gst_seconds` +##### Method `to_gst_seconds` {#anise.time.Epoch.to_gst_seconds} > def to_gst_seconds( > self, @@ -1184,9 +2138,10 @@ NOTE: This function will return an error if the centuries past GST time are not > ) Returns seconds past GST (Galileo) Time Epoch +:rtype: float -##### Method `to_isoformat` +##### Method `to_isoformat` {#anise.time.Epoch.to_isoformat} > def to_isoformat( > self, @@ -1194,9 +2149,10 @@ Returns seconds past GST (Galileo) Time Epoch > ) The standard ISO format of this epoch (six digits of subseconds) in the _current_ time scale, refer to for format options. +:rtype: str -##### Method `to_jde_et` +##### Method `to_jde_et` {#anise.time.Epoch.to_jde_et} > def to_jde_et( > self, @@ -1204,8 +2160,11 @@ The standard ISO format of this epoch (six digits of subseconds) in the _current > unit > ) +:type unit: Unit +:rtype: float + -##### Method `to_jde_et_days` +##### Method `to_jde_et_days` {#anise.time.Epoch.to_jde_et_days} > def to_jde_et_days( > self, @@ -1213,17 +2172,20 @@ The standard ISO format of this epoch (six digits of subseconds) in the _current > ) Returns the Ephemeris Time JDE past epoch +:rtype: float -##### Method `to_jde_et_duration` +##### Method `to_jde_et_duration` {#anise.time.Epoch.to_jde_et_duration} > def to_jde_et_duration( > self, > / > ) +:rtype: Duration + -##### Method `to_jde_tai` +##### Method `to_jde_tai` {#anise.time.Epoch.to_jde_tai} > def to_jde_tai( > self, @@ -1232,9 +2194,11 @@ Returns the Ephemeris Time JDE past epoch > ) Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) in desired Duration::Unit +:type unit: Unit +:rtype: float -##### Method `to_jde_tai_days` +##### Method `to_jde_tai_days` {#anise.time.Epoch.to_jde_tai_days} > def to_jde_tai_days( > self, @@ -1244,9 +2208,10 @@ Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) in desired Duration Returns the Julian days from epoch 01 Jan -4713, 12:00 (noon) as explained in "Fundamentals of astrodynamics and applications", Vallado et al. 4th edition, page 182, and on [Wikipedia](https://en.wikipedia.org/wiki/Julian_day). +:rtype: float -##### Method `to_jde_tai_duration` +##### Method `to_jde_tai_duration` {#anise.time.Epoch.to_jde_tai_duration} > def to_jde_tai_duration( > self, @@ -1254,9 +2219,10 @@ as explained in "Fundamentals of astrodynamics and applications", Vallado et al. > ) Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) as a Duration +:rtype: Duration -##### Method `to_jde_tai_seconds` +##### Method `to_jde_tai_seconds` {#anise.time.Epoch.to_jde_tai_seconds} > def to_jde_tai_seconds( > self, @@ -1264,9 +2230,10 @@ Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) as a Duration > ) Returns the Julian seconds in TAI. +:rtype: float -##### Method `to_jde_tdb_days` +##### Method `to_jde_tdb_days` {#anise.time.Epoch.to_jde_tdb_days} > def to_jde_tdb_days( > self, @@ -1274,17 +2241,20 @@ Returns the Julian seconds in TAI. > ) Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI (cf. ) +:rtype: float -##### Method `to_jde_tdb_duration` +##### Method `to_jde_tdb_duration` {#anise.time.Epoch.to_jde_tdb_duration} > def to_jde_tdb_duration( > self, > / > ) +:rtype: Duration + -##### Method `to_jde_tt_days` +##### Method `to_jde_tt_days` {#anise.time.Epoch.to_jde_tt_days} > def to_jde_tt_days( > self, @@ -1292,17 +2262,20 @@ Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time > ) Returns days past Julian epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float -##### Method `to_jde_tt_duration` +##### Method `to_jde_tt_duration` {#anise.time.Epoch.to_jde_tt_duration} > def to_jde_tt_duration( > self, > / > ) +:rtype: Duration + -##### Method `to_jde_utc_days` +##### Method `to_jde_utc_days` {#anise.time.Epoch.to_jde_utc_days} > def to_jde_utc_days( > self, @@ -1310,19 +2283,21 @@ Returns days past Julian epoch in Terrestrial Time (TT) (previously called Terre > ) Returns the Julian days in UTC. +:rtype: float -##### Method `to_jde_utc_duration` +##### Method `to_jde_utc_duration` {#anise.time.Epoch.to_jde_utc_duration} > def to_jde_utc_duration( > self, > / > ) -Returns the Julian days in UTC as a [Duration](#time.Duration "time.Duration") +Returns the Julian days in UTC as a [Duration](#anise.time.Duration "anise.time.Duration") +:rtype: Duration -##### Method `to_jde_utc_seconds` +##### Method `to_jde_utc_seconds` {#anise.time.Epoch.to_jde_utc_seconds} > def to_jde_utc_seconds( > self, @@ -1330,9 +2305,10 @@ Returns the Julian days in UTC as a [Duration](#time.Duration "time.Durati > ) Returns the Julian Days in UTC seconds. +:rtype: float -##### Method `to_mjd_tai` +##### Method `to_mjd_tai` {#anise.time.Epoch.to_mjd_tai} > def to_mjd_tai( > self, @@ -1341,9 +2317,11 @@ Returns the Julian Days in UTC seconds. > ) Returns this epoch as a duration in the requested units in MJD TAI +:type unit: Unit +:rtype: float -##### Method `to_mjd_tai_days` +##### Method `to_mjd_tai_days` {#anise.time.Epoch.to_mjd_tai_days} > def to_mjd_tai_days( > self, @@ -1352,9 +2330,10 @@ Returns this epoch as a duration in the requested units in MJD TAI as\_mjd\_days creates an Epoch from the provided Modified Julian Date in days as explained [here](http://tycho.usno.navy.mil/mjd.html). MJD epoch is Modified Julian Day at 17 November 1858 at midnight. +:rtype: float -##### Method `to_mjd_tai_seconds` +##### Method `to_mjd_tai_seconds` {#anise.time.Epoch.to_mjd_tai_seconds} > def to_mjd_tai_seconds( > self, @@ -1362,9 +2341,10 @@ Returns this epoch as a duration in the requested units in MJD TAI > ) Returns the Modified Julian Date in seconds TAI. +:rtype: float -##### Method `to_mjd_tt_days` +##### Method `to_mjd_tt_days` {#anise.time.Epoch.to_mjd_tt_days} > def to_mjd_tt_days( > self, @@ -1372,17 +2352,20 @@ Returns the Modified Julian Date in seconds TAI. > ) Returns days past Modified Julian epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float -##### Method `to_mjd_tt_duration` +##### Method `to_mjd_tt_duration` {#anise.time.Epoch.to_mjd_tt_duration} > def to_mjd_tt_duration( > self, > / > ) +:rtype: Duration + -##### Method `to_mjd_utc` +##### Method `to_mjd_utc` {#anise.time.Epoch.to_mjd_utc} > def to_mjd_utc( > self, @@ -1391,9 +2374,11 @@ Returns days past Modified Julian epoch in Terrestrial Time (TT) (previously cal > ) Returns the Modified Julian Date in the provided unit in UTC. +:type unit: Unit +:rtype: float -##### Method `to_mjd_utc_days` +##### Method `to_mjd_utc_days` {#anise.time.Epoch.to_mjd_utc_days} > def to_mjd_utc_days( > self, @@ -1401,9 +2386,10 @@ Returns the Modified Julian Date in the provided unit in UTC. > ) Returns the Modified Julian Date in days UTC. +:rtype: float -##### Method `to_mjd_utc_seconds` +##### Method `to_mjd_utc_seconds` {#anise.time.Epoch.to_mjd_utc_seconds} > def to_mjd_utc_seconds( > self, @@ -1411,9 +2397,10 @@ Returns the Modified Julian Date in days UTC. > ) Returns the Modified Julian Date in seconds UTC. +:rtype: float -##### Method `to_nanoseconds_in_time_scale` +##### Method `to_nanoseconds_in_time_scale` {#anise.time.Epoch.to_nanoseconds_in_time_scale} > def to_nanoseconds_in_time_scale( > self, @@ -1426,8 +2413,11 @@ This will return an overflow error if more than one century has past since the r If this is _not_ an issue, you should use epoch.to\_duration\_in\_time\_scale().to\_parts() to retrieve both the centuries and the nanoseconds in that century. +:type time_scale: TimeScale +:rtype: int + -##### Method `to_qzsst_days` +##### Method `to_qzsst_days` {#anise.time.Epoch.to_qzsst_days} > def to_qzsst_days( > self, @@ -1435,19 +2425,21 @@ in that century. > ) Returns days past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float -##### Method `to_qzsst_duration` +##### Method `to_qzsst_duration` {#anise.time.Epoch.to_qzsst_duration} > def to_qzsst_duration( > self, > / > ) -Returns [Duration](#time.Duration "time.Duration") past QZSS time Epoch. +Returns [Duration](#anise.time.Duration "anise.time.Duration") past QZSS time Epoch. +:rtype: Duration -##### Method `to_qzsst_nanoseconds` +##### Method `to_qzsst_nanoseconds` {#anise.time.Epoch.to_qzsst_nanoseconds} > def to_qzsst_nanoseconds( > self, @@ -1456,9 +2448,10 @@ Returns [Duration](#time.Duration "time.Duration") past QZSS time E Returns nanoseconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). NOTE: This function will return an error if the centuries past QZSST time are not zero. +:rtype: int -##### Method `to_qzsst_seconds` +##### Method `to_qzsst_seconds` {#anise.time.Epoch.to_qzsst_seconds} > def to_qzsst_seconds( > self, @@ -1466,9 +2459,10 @@ NOTE: This function will return an error if the centuries past QZSST time are no > ) Returns seconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). +:rtype: float -##### Method `to_rfc3339` +##### Method `to_rfc3339` {#anise.time.Epoch.to_rfc3339} > def to_rfc3339( > self, @@ -1476,9 +2470,10 @@ Returns seconds past QZSS Time Epoch, defined as UTC midnight of January 5th to > ) Returns this epoch in UTC in the RFC3339 format +:rtype: str -##### Method `to_tai` +##### Method `to_tai` {#anise.time.Epoch.to_tai} > def to_tai( > self, @@ -1487,9 +2482,11 @@ Returns this epoch in UTC in the RFC3339 format > ) Returns the epoch as a floating point value in the provided unit +:type unit: Unit +:rtype: float -##### Method `to_tai_days` +##### Method `to_tai_days` {#anise.time.Epoch.to_tai_days} > def to_tai_days( > self, @@ -1497,9 +2494,10 @@ Returns the epoch as a floating point value in the provided unit > ) Returns the number of days since J1900 in TAI +:rtype: float -##### Method `to_tai_duration` +##### Method `to_tai_duration` {#anise.time.Epoch.to_tai_duration} > def to_tai_duration( > self, @@ -1507,9 +2505,10 @@ Returns the number of days since J1900 in TAI > ) Returns this time in a Duration past J1900 counted in TAI +:rtype: Duration -##### Method `to_tai_parts` +##### Method `to_tai_parts` {#anise.time.Epoch.to_tai_parts} > def to_tai_parts( > self, @@ -1517,9 +2516,10 @@ Returns this time in a Duration past J1900 counted in TAI > ) Returns the TAI parts of this duration +:rtype: typing.Tuple -##### Method `to_tai_seconds` +##### Method `to_tai_seconds` {#anise.time.Epoch.to_tai_seconds} > def to_tai_seconds( > self, @@ -1527,9 +2527,10 @@ Returns the TAI parts of this duration > ) Returns the number of TAI seconds since J1900 +:rtype: float -##### Method `to_tdb_centuries_since_j2000` +##### Method `to_tdb_centuries_since_j2000` {#anise.time.Epoch.to_tdb_centuries_since_j2000} > def to_tdb_centuries_since_j2000( > self, @@ -1537,9 +2538,10 @@ Returns the number of TAI seconds since J1900 > ) Returns the number of centuries since Dynamic Barycentric Time (TDB) J2000 (used for Archinal et al. rotations) +:rtype: float -##### Method `to_tdb_days_since_j2000` +##### Method `to_tdb_days_since_j2000` {#anise.time.Epoch.to_tdb_days_since_j2000} > def to_tdb_days_since_j2000( > self, @@ -1547,9 +2549,10 @@ Returns the number of centuries since Dynamic Barycentric Time (TDB) J2000 (used > ) Returns the number of days since Dynamic Barycentric Time (TDB) J2000 (used for Archinal et al. rotations) +:rtype: float -##### Method `to_tdb_duration` +##### Method `to_tdb_duration` {#anise.time.Epoch.to_tdb_duration} > def to_tdb_duration( > self, @@ -1563,7 +2566,7 @@ Given the embedded sine functions in the equation to compute the difference betw past J2000, one cannot solve the revert the operation analytically. Instead, we iterate until the value no longer changes. 1. Assume that the TAI duration is in fact the TDB seconds from J2000. -2. Offset to J2000 because [Epoch](#time.Epoch "time.Epoch") stores everything in the J1900 but the TDB duration is in J2000. +2. Offset to J2000 because [Epoch](#anise.time.Epoch "anise.time.Epoch") stores everything in the J1900 but the TDB duration is in J2000. 3. Compute the offset g due to the TDB computation with the current value of the TDB seconds (defined in step 1). 4. Subtract that offset to the latest TDB seconds and store this as a new candidate for the true TDB seconds value. 5. Compute the difference between this candidate and the previous one. If the difference is less than one nanosecond, stop iteration. @@ -1571,8 +2574,10 @@ past J2000, one cannot solve the revert the operation analytically. Instead, we 7. At this stage, we have a good approximation of the TDB seconds since J2000. 8. Reverse the algorithm given that approximation: compute the g offset, compute the difference between TDB and TAI, add the TT offset (32.184 s), and offset by the difference between J1900 and J2000. +:rtype: Duration + -##### Method `to_tdb_seconds` +##### Method `to_tdb_seconds` {#anise.time.Epoch.to_tdb_seconds} > def to_tdb_seconds( > self, @@ -1580,9 +2585,40 @@ past J2000, one cannot solve the revert the operation analytically. Instead, we > ) Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI (cf. ) +:rtype: float + + +##### Method `to_time_of_week` {#anise.time.Epoch.to_time_of_week} + +> def to_time_of_week( +> self, +> / +> ) + +Converts this epoch into the time of week, represented as a rolling week counter into that time scale +and the number of nanoseconds elapsed in current week (since closest Sunday midnight). +This is usually how GNSS receivers describe a timestamp. +:rtype: typing.Tuple[int] + + +##### Method `to_time_scale` {#anise.time.Epoch.to_time_scale} + +> def to_time_scale( +> self, +> /, +> ts +> ) + +Converts self to another time scale + +As per the [Rust naming convention](https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv), +this borrows an Epoch and returns an owned Epoch. + +:type ts: TimeScale +:rtype: Epoch -##### Method `to_tt_centuries_j2k` +##### Method `to_tt_centuries_j2k` {#anise.time.Epoch.to_tt_centuries_j2k} > def to_tt_centuries_j2k( > self, @@ -1590,9 +2626,10 @@ Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time > ) Returns the centuries passed J2000 TT +:rtype: float -##### Method `to_tt_days` +##### Method `to_tt_days` {#anise.time.Epoch.to_tt_days} > def to_tt_days( > self, @@ -1600,19 +2637,21 @@ Returns the centuries passed J2000 TT > ) Returns days past TAI epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float -##### Method `to_tt_duration` +##### Method `to_tt_duration` {#anise.time.Epoch.to_tt_duration} > def to_tt_duration( > self, > / > ) -Returns [Duration](#time.Duration "time.Duration") past TAI epoch in Terrestrial Time (TT). +Returns [Duration](#anise.time.Duration "anise.time.Duration") past TAI epoch in Terrestrial Time (TT). +:rtype: Duration -##### Method `to_tt_seconds` +##### Method `to_tt_seconds` {#anise.time.Epoch.to_tt_seconds} > def to_tt_seconds( > self, @@ -1620,9 +2659,10 @@ Returns [Duration](#time.Duration "time.Duration") past TAI epoch i > ) Returns seconds past TAI epoch in Terrestrial Time (TT) (previously called Terrestrial Dynamical Time (TDT)) +:rtype: float -##### Method `to_tt_since_j2k` +##### Method `to_tt_since_j2k` {#anise.time.Epoch.to_tt_since_j2k} > def to_tt_since_j2k( > self, @@ -1630,9 +2670,10 @@ Returns seconds past TAI epoch in Terrestrial Time (TT) (previously called Terre > ) Returns the duration past J2000 TT +:rtype: Duration -##### Method `to_unix` +##### Method `to_unix` {#anise.time.Epoch.to_unix} > def to_unix( > self, @@ -1641,9 +2682,11 @@ Returns the duration past J2000 TT > ) Returns the duration since the UNIX epoch in the provided unit. +:type unit: Unit +:rtype: float -##### Method `to_unix_days` +##### Method `to_unix_days` {#anise.time.Epoch.to_unix_days} > def to_unix_days( > self, @@ -1651,9 +2694,10 @@ Returns the duration since the UNIX epoch in the provided unit. > ) Returns the number days since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float -##### Method `to_unix_duration` +##### Method `to_unix_duration` {#anise.time.Epoch.to_unix_duration} > def to_unix_duration( > self, @@ -1661,9 +2705,10 @@ Returns the number days since the UNIX epoch defined 01 Jan 1970 midnight UTC. > ) Returns the Duration since the UNIX epoch UTC midnight 01 Jan 1970. +:rtype: Duration -##### Method `to_unix_milliseconds` +##### Method `to_unix_milliseconds` {#anise.time.Epoch.to_unix_milliseconds} > def to_unix_milliseconds( > self, @@ -1671,9 +2716,10 @@ Returns the Duration since the UNIX epoch UTC midnight 01 Jan 1970. > ) Returns the number milliseconds since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float -##### Method `to_unix_seconds` +##### Method `to_unix_seconds` {#anise.time.Epoch.to_unix_seconds} > def to_unix_seconds( > self, @@ -1681,9 +2727,10 @@ Returns the number milliseconds since the UNIX epoch defined 01 Jan 1970 midnigh > ) Returns the number seconds since the UNIX epoch defined 01 Jan 1970 midnight UTC. +:rtype: float -##### Method `to_utc` +##### Method `to_utc` {#anise.time.Epoch.to_utc} > def to_utc( > self, @@ -1692,9 +2739,11 @@ Returns the number seconds since the UNIX epoch defined 01 Jan 1970 midnight UTC > ) Returns the number of UTC seconds since the TAI epoch +:type unit: Unit +:rtype: float -##### Method `to_utc_days` +##### Method `to_utc_days` {#anise.time.Epoch.to_utc_days} > def to_utc_days( > self, @@ -1702,9 +2751,10 @@ Returns the number of UTC seconds since the TAI epoch > ) Returns the number of UTC days since the TAI epoch +:rtype: float -##### Method `to_utc_duration` +##### Method `to_utc_duration` {#anise.time.Epoch.to_utc_duration} > def to_utc_duration( > self, @@ -1712,9 +2762,10 @@ Returns the number of UTC days since the TAI epoch > ) Returns this time in a Duration past J1900 counted in UTC +:rtype: Duration -##### Method `to_utc_seconds` +##### Method `to_utc_seconds` {#anise.time.Epoch.to_utc_seconds} > def to_utc_seconds( > self, @@ -1722,9 +2773,58 @@ Returns this time in a Duration past J1900 counted in UTC > ) Returns the number of UTC seconds since the TAI epoch +:rtype: float + + +##### Method `todatetime` {#anise.time.Epoch.todatetime} + +> def todatetime( +> self, +> / +> ) + +Returns a Python datetime object from this Epoch (truncating the nanoseconds away) +:rtype: datetime.datetime + + +##### Method `weekday` {#anise.time.Epoch.weekday} + +> def weekday( +> self, +> / +> ) + +Returns weekday (uses the TAI representation for this calculation). +:rtype: Weekday + + +##### Method `weekday_in_time_scale` {#anise.time.Epoch.weekday_in_time_scale} + +> def weekday_in_time_scale( +> self, +> /, +> time_scale +> ) + +Returns the weekday in provided time scale **ASSUMING** that the reference epoch of that time scale is a Monday. +You _probably_ do not want to use this. You probably either want weekday() or weekday\_utc(). +Several time scales do _not_ have a reference day that's on a Monday, e.g. BDT. +:type time_scale: TimeScale +:rtype: Weekday + + +##### Method `weekday_utc` {#anise.time.Epoch.weekday_utc} + +> def weekday_utc( +> self, +> / +> ) + +Returns weekday in UTC timescale +:rtype: Weekday -##### Method `year` +##### Method `year` {#anise.time.Epoch.year} > def year( > self, @@ -1732,9 +2832,10 @@ Returns the number of UTC seconds since the TAI epoch > ) Returns the number of Gregorian years of this epoch in the current time scale. +:rtype: int -##### Method `year_days_of_year` +##### Method `year_days_of_year` {#anise.time.Epoch.year_days_of_year} > def year_days_of_year( > self, @@ -1742,18 +2843,33 @@ Returns the number of Gregorian years of this epoch in the current time scale. > ) Returns the year and the days in the year so far (days of year). +:rtype: typing.Tuple + + +### Class `HifitimeError` {#anise.time.HifitimeError} + +> class HifitimeError( +> *args, +> **kwargs +> ) -### Class `LatestLeapSeconds` +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) + + +### Class `LatestLeapSeconds` {#anise.time.LatestLeapSeconds} > class LatestLeapSeconds -List of leap seconds from . +List of leap seconds from . This list corresponds the number of seconds in TAI to the UTC offset and to whether it was an announced leap second or not. The unannoucned leap seconds come from dat.c in the SOFA library. -### Class `LeapSecondsFile` +### Class `LeapSecondsFile` {#anise.time.LeapSecondsFile} > class LeapSecondsFile( > path @@ -1761,8 +2877,153 @@ The unannoucned leap seconds come from dat.c in the SOFA library. A leap second provider that uses an IERS formatted leap seconds file. +(Python documentation hints) +:type path: str +:rtype: LeapSecondsFile + + +### Class `MonthName` {#anise.time.MonthName} + +> class MonthName( +> ... +> ) + + +#### Class variables + + +##### Variable `April` {#anise.time.MonthName.April} + + +##### Variable `August` {#anise.time.MonthName.August} + + +##### Variable `December` {#anise.time.MonthName.December} + + +##### Variable `February` {#anise.time.MonthName.February} + + +##### Variable `January` {#anise.time.MonthName.January} + + +##### Variable `July` {#anise.time.MonthName.July} + + +##### Variable `June` {#anise.time.MonthName.June} + + +##### Variable `March` {#anise.time.MonthName.March} + + +##### Variable `May` {#anise.time.MonthName.May} + + +##### Variable `November` {#anise.time.MonthName.November} + + +##### Variable `October` {#anise.time.MonthName.October} + + +##### Variable `September` {#anise.time.MonthName.September} + + +### Class `ParsingError` {#anise.time.ParsingError} + +> class ParsingError( +> *args, +> **kwargs +> ) + -### Class `TimeScale` +#### Ancestors (in MRO) + +* [builtins.Exception](#builtins.Exception) +* [builtins.BaseException](#builtins.BaseException) + + +### Class `Polynomial` {#anise.time.Polynomial} + +> class Polynomial( +> ... +> ) + +Interpolation [Polynomial] used for example in [TimeScale] +maintenance, precise monitoring or conversions. + +(Python documentation hints) +:type constant: Duration +:type rate: Duration +:type accel: Duration +:rtype: Polynomial + + +#### Methods + + +##### Method `correction_duration` {#anise.time.Polynomial.correction_duration} + +> def correction_duration( +> self, +> /, +> time_interval +> ) + +Calculate the correction (as [Duration] once again) from [Self] and given +the interpolation time interval +:type time_interval: Duration +:rtype: Duration + + +##### Method `from_constant_offset` {#anise.time.Polynomial.from_constant_offset} + +> def from_constant_offset( +> constant +> ) + +Create a [Polynomial] structure that is only made of a static offset +:type constant: Duration +:rtype: Polynomial + + +##### Method `from_constant_offset_nanoseconds` {#anise.time.Polynomial.from_constant_offset_nanoseconds} + +> def from_constant_offset_nanoseconds( +> nanos +> ) + +Create a [Polynomial] structure from a static offset expressed in nanoseconds +:type nanos: float +:rtype: Polynomial + + +##### Method `from_offset_and_rate` {#anise.time.Polynomial.from_offset_and_rate} + +> def from_offset_and_rate( +> constant, +> rate +> ) + +Create a [Polynomial] structure from both static offset and rate of change: +:type constant: Duration +:type rate: Duration +:rtype: Polynomial + + +##### Method `from_offset_rate_nanoseconds` {#anise.time.Polynomial.from_offset_rate_nanoseconds} + +> def from_offset_rate_nanoseconds( +> offset_ns, +> drift_ns_s +> ) + +Create a [Polynomial] structure from a static offset and drift, in nanoseconds and nanoseconds.s⁻¹ +:type offset_ns: float +:type drift_ns_s: float +:rtype: Polynomial + + +### Class `TimeScale` {#anise.time.TimeScale} > class TimeScale( > ... @@ -1774,37 +3035,37 @@ Enum of the different time systems available #### Class variables -##### Variable `BDT` +##### Variable `BDT` {#anise.time.TimeScale.BDT} -##### Variable `ET` +##### Variable `ET` {#anise.time.TimeScale.ET} -##### Variable `GPST` +##### Variable `GPST` {#anise.time.TimeScale.GPST} -##### Variable `GST` +##### Variable `GST` {#anise.time.TimeScale.GST} -##### Variable `QZSST` +##### Variable `QZSST` {#anise.time.TimeScale.QZSST} -##### Variable `TAI` +##### Variable `TAI` {#anise.time.TimeScale.TAI} -##### Variable `TDB` +##### Variable `TDB` {#anise.time.TimeScale.TDB} -##### Variable `TT` +##### Variable `TT` {#anise.time.TimeScale.TT} -##### Variable `UTC` +##### Variable `UTC` {#anise.time.TimeScale.UTC} #### Methods -##### Method `uses_leap_seconds` +##### Method `uses_leap_seconds` {#anise.time.TimeScale.uses_leap_seconds} > def uses_leap_seconds( > self, @@ -1812,9 +3073,10 @@ Enum of the different time systems available > ) Returns true if self takes leap seconds into account +:rtype: bool -### Class `TimeSeries` +### Class `TimeSeries` {#anise.time.TimeSeries} > class TimeSeries( > start, @@ -1825,8 +3087,15 @@ Returns true if self takes leap seconds into account An iterator of a sequence of evenly spaced Epochs. +(Python documentation hints) +:type start: Epoch +:type end: Epoch +:type step: Duration +:type inclusive: bool +:rtype: TimeSeries + -### Class `Unit` +### Class `Unit` {#anise.time.Unit} > class Unit( > ... @@ -1838,37 +3107,37 @@ An Enum to perform time unit conversions. #### Class variables -##### Variable `Century` +##### Variable `Century` {#anise.time.Unit.Century} -##### Variable `Day` +##### Variable `Day` {#anise.time.Unit.Day} -##### Variable `Hour` +##### Variable `Hour` {#anise.time.Unit.Hour} -##### Variable `Microsecond` +##### Variable `Microsecond` {#anise.time.Unit.Microsecond} -##### Variable `Millisecond` +##### Variable `Millisecond` {#anise.time.Unit.Millisecond} -##### Variable `Minute` +##### Variable `Minute` {#anise.time.Unit.Minute} -##### Variable `Nanosecond` +##### Variable `Nanosecond` {#anise.time.Unit.Nanosecond} -##### Variable `Second` +##### Variable `Second` {#anise.time.Unit.Second} -##### Variable `Week` +##### Variable `Week` {#anise.time.Unit.Week} #### Methods -##### Method `from_seconds` +##### Method `from_seconds` {#anise.time.Unit.from_seconds} > def from_seconds( > self, @@ -1876,7 +3145,7 @@ An Enum to perform time unit conversions. > ) -##### Method `in_seconds` +##### Method `in_seconds` {#anise.time.Unit.in_seconds} > def in_seconds( > self, @@ -1884,11 +3153,42 @@ An Enum to perform time unit conversions. > ) -### Class `Ut1Provider` +### Class `Ut1Provider` {#anise.time.Ut1Provider} > class Ut1Provider A structure storing all of the TAI-UT1 data + +### Class `Weekday` {#anise.time.Weekday} + +> class Weekday( +> ... +> ) + + +#### Class variables + + +##### Variable `Friday` {#anise.time.Weekday.Friday} + + +##### Variable `Monday` {#anise.time.Weekday.Monday} + + +##### Variable `Saturday` {#anise.time.Weekday.Saturday} + + +##### Variable `Sunday` {#anise.time.Weekday.Sunday} + + +##### Variable `Thursday` {#anise.time.Weekday.Thursday} + + +##### Variable `Tuesday` {#anise.time.Weekday.Tuesday} + + +##### Variable `Wednesday` {#anise.time.Weekday.Wednesday} + ----- -Generated by *pdoc* 0.10.0 (). +Generated by *pdoc* 0.11.6 (). diff --git a/docs/anise/reference/api/python/utils.md b/docs/anise/reference/api/python/utils.md new file mode 100644 index 0000000..65942f0 --- /dev/null +++ b/docs/anise/reference/api/python/utils.md @@ -0,0 +1,45 @@ +# Module `anise.utils` {#anise.utils} + + +## Functions + + +### Function `convert_fk` {#anise.utils.convert_fk} + +> def convert_fk( +> fk_file_path, +> anise_output_path, +> show_comments=None, +> overwrite=None +> ) + +Converts a KPL/FK file, that defines frame constants like fixed rotations, and frame name to ID mappings into the EulerParameterDataSet equivalent ANISE file. +KPL/FK files must be converted into "PCA" (Planetary Constant ANISE) files before being loaded into ANISE. + +:type fk_file_path: str +:type anise_output_path: str +:type show_comments: bool, optional +:type overwrite: bool, optional +:rtype: None + + +### Function `convert_tpc` {#anise.utils.convert_tpc} + +> def convert_tpc( +> pck_file_path, +> gm_file_path, +> anise_output_path, +> overwrite=None +> ) + +Converts two KPL/TPC files, one defining the planetary constants as text, and the other defining the gravity parameters, into the PlanetaryDataSet equivalent ANISE file. +KPL/TPC files must be converted into "PCA" (Planetary Constant ANISE) files before being loaded into ANISE. + +:type pck_file_path: str +:type gm_file_path: str +:type anise_output_path: str +:type overwrite: bool, optional +:rtype: None + +----- +Generated by *pdoc* 0.11.6 (). diff --git a/mkdocs.yml b/mkdocs.yml index 0f4d436..0bb0092 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,9 +112,10 @@ nav: - Lagrange interpolation: anise/reference/mathspec/interpolation/lagrange.md - Python API: - ANISE Python: anise/reference/api/python/index.md - - Astro: anise/reference/api/python/astro/index.md - - Constants: anise/reference/api/python/astro/constants.md + - Astro: anise/reference/api/python/astro.md + - Constants: anise/reference/api/python/constants.md - Time: anise/reference/api/python/time.md + - Utils: anise/reference/api/python/utils.md - Rust API: anise/reference/api/rust/index.md - Pricing: pricing.md diff --git a/reqs.txt b/reqs.txt index 5078579..56445ba 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,6 +1,6 @@ mkdocs==1.6.1 -mkdocs-git-revision-date-localized-plugin==1.3.0 +mkdocs-git-revision-date-localized-plugin==1.4.7 mkdocs-glightbox==0.4.0 mkdocs-jupyter==0.25.1 -mkdocs-material==9.6.7 +mkdocs-material==9.6.14 mkdocs-redirects==1.2.2