.. _printing_processing_results: ################################### Printing and processing the results ################################### The results of the numerical propagation are stored in the :ref:`propagation results `, which can be used to perform further analysis, and retrieve the details of the propagation process. In addition, there are a number of processing steps and terminal outputs that Tudat can perform before, during and after the propagation. Although such settings can be provided directly when creating propagator settings (for instance, when calling the :func:`~tudatpy.dynamics.propagation_setup.propagator.translational` function), it is advised to modify these settings afterwards: .. code-block:: python propagator_settings = propagator.translational( ... ) console_print_settings = propagator_settings.print_settings post_processing_settings = propagator_settings.processing_settings Here, the resulting settings object for console printing and post-processing are of type :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings` and :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings` (with derived class :class:`~tudatpy.dynamics.propagation_setup.propagator.SingleArcPropagatorProcessingSettings` for single-arc propagation), respectively. Below, the options available in both these settings objects are described in more detail. .. _auto_processing: Automatic processing ==================== By default, Tudat will save the propagated states and dependent variables at each time step, and return these the user after the propagation is finished. Below, a number of additions/extensions to this behaviour are described, where the propagated states that are returned are used and/or processed before being returned to the user. .. _setting_results_post_propagation: Updating ephemerides (and other environment models) --------------------------------------------------- Tudat can be set up to automatically use the results of the numerical propagation to reset properties in the environment upon the successful completion of the propagation. This option can be toggled using the boolean attribute :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings.set_integrated_result` of the :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings` class: .. code-block:: python propagator_settings = propagator.translational( ... ) propagator_settings.processing_settings.set_integrated_result = True Specifically, this will result in: * Translational dynamics: use the numerical results to reset the ephemeris of the body with (using the default) a 6-th order Lagrange interpolation scheme to create a tabulated ephemeris * Rotational dynamics: use the numerical results to reset the rotational ephemeris of the body with (using the default) a 6-th order Lagrange interpolation scheme to create a tabulated rotation model * Mass dynamics: use the numerical results to reset the mass function of the body with (using the default) a 6-th order Lagrange interpolation scheme * Multi-type dynamics: automatically processes all of the constituent dynamics as listed above * Custom dynamics: no action To be able to perform the reset of the ephemeris (or other environment model), the existing ephemeris must be of the suitable type. This means that it must either be a tabulated ephemeris already (in which case the tabulation is reset) or the body must contain no ephemeris (in which case one is created on the fly when :ref:`creating the dynamics simulator `). In cases where a user wants to use a non-tabulated ephemeris for a body, but still use the functionality described here to reset the ephemeris later on, the ephemeris type of the body can be redefined using :func:`~tudatpy.dynamics.environment_setup.ephemeris.tabulated_from_existing` when :ref:`defining the body settings `. In essence, this converts any ephemeris into a tabulated ephemeris, where the tabulated ephemeris is populated by states from the original (non-tabulated) ephemeris. For specific applications, most notably a state estimation, a user may want the numerical solution to *only* be used to reset the environment, while not needing access to the numerical results directly. To enable this behavior, the boolean attribute :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings.clear_solution` of the :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings` class is provided. .. code-block:: python propagator_settings = propagator.translational( ... ) propagator_settings.processing_settings.set_integrated_result = True propagator_settings.processing_settings.clear_solution = True When set to true, the numerical results of the propagation are completely deleted after the propagation is performed. When this option is selected, the numerical results 'live on' *only* in the environment models that have been reset, but are no longer available from the :ref:`propagation results `. This option may be attractive when memory usage of the application is a concern. .. _saving_cadence: Reduced saving cadence ---------------------- By definition, Tudat saves and returns the state and dependent variables at *every* full step of the numerical integration. For long numerical integrations, this can result in excessively long data structures being stored in memory, potentially leading to issues. Options are provided to modify the cadence at which data is saved, using the :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings.results_save_frequency_in_steps` and :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings.results_save_frequency_in_seconds` attributes of the :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings` class, which allow the results to be saved only every X steps, or every Y seconds (of time in the simulation). For instance, using: .. code-block:: python propagator_settings = propagator.translational( ... ) propagator_settings.processing_settings.results_save_frequency_in_steps = 3 The results are only saved every third time step. By using .. code-block:: python propagator_settings = propagator.translational( ... ) propagator_settings.processing_settings.results_save_frequency_in_steps = 3 propagator_settings.processing_settings.results_save_frequency_in_seconds = 60.0 the results are saved every third time step *or* every 60 seconds of time in the simulation, whichever one occurs first since the previous saved data point. Multi- and hybrid-arc considerations ------------------------------------ For the multi- and hybrid arc propagation, the setting of the numerical results in the environment, and the clearing of the numerical solution (as described :ref:`above `), is *always* consistent between all the arcs. As a result, these settings in the constituent single-arc propagation settings will be overridden by the settings in the multi- or hybrid-arc propagation settings. Objects of type :class:`~tudatpy.dynamics.propagation_setup.propagator.MultiArcPropagatorProcessingSettings` or :class:`~tudatpy.dynamics.propagation_setup.propagator.HybridArcPropagatorProcessingSettings` are automatically created and stored in the propagator settings when creating multi- or hybrid-arc propagator settings, and can be retrieved similarly as for the single-arc settings: .. code-block:: python multiarc_propagator_settings = propagator.multi_arc( ... ) post_processing_settings = propagator_settings.processing_settings To reset the dynamics of a body with the results of a multi-arc propagation (e.g. if the :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagatorProcessingSettings.set_integrated_result` option is set to true), the ephemeris of this body must be a multi-arc ephemeris. If the body has no ephemeris before propagation, one is created on the fly when :ref:`creating the dynamics simulator `. In cases where a user wants to use a single-arc ephemeris for a body, but still use the functionality described here to reset the ephemeris from multi-arc results later on, the ephemeris type can be forced to multi-arc by using the :attr:`~tudatpy.dynamics.environment_setup.ephemeris.EphemerisSettings.make_multi_arc_ephemeris` attribute of the :class:`~tudatpy.dynamics.environment_setup.ephemeris.EphemerisSettings` when :ref:`defining the body settings `. For example, to reset the ephemeris of the Earth from a multi-arc propagation result, the following can be used to permit this: .. code-block:: python # Create body settings body_settings = environment_setup.get_default_body_settings( ... ) body_settings.get("Earth").ephemeris_settings.make_multi_arc_ephemeris = True The cadence at which data is saved during the propagation (see :ref:`above `) may vary per arc. The list of single-arc settings can be retrieved from the results as follows: .. code-block:: python multiarc_propagator_settings = propagator.multi_arc( ... ) single_arc_processing_settings = multiarc_propagator_settings.single_arc_settings Settings to print data to the console (see :ref:`below `) is also defined separately per arc. Additional options for multi- and hybrid-arc propagation are provided :ref:`below `. .. _console_output: Console Output ============== Tudat also provides a range of options on information to be printed to the console *during* the process of the propagation. These settings are specified through a :class:`~tudatpy.dynamics.propagation_setup.PropagationPrintSettings` object, which can be retried from single-arc propagator settings through: .. code-block:: python propagator_settings = propagator.translational( ... ) console_print_settings = propagator_settings.print_settings A full list of print options is provide in the API documentation. Typical examples of information that can be printed to the console are: * The indices in the full dependent variable vector (:attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.print_dependent_variable_indices`; see :ref:`dependent_variables`) where each separate dependent variable is stored, with a brief text description of the associated dependent variable (printed before the propagation starts) * The current time and state can be printed *during* the propagation (:attr:`~tudatpy.dynamics.propagation_setup.PropagationPrintSettings.state_print_interval`), at a simulation time interval specified by the user * Total runtime, number of function evaluations of the state derivative, and the reason for the termination of the propagation (printed after the propagation is finished; see :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.print_propagation_clock_time`, :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.print_number_of_function_evaluations` and :attr:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.print_termination_reason`) In most cases, the separate print settings (as attributes of the :class:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings` class) are defined by a boolean (print this information: yes or no). For specific cases, such as the interval at which information should be printed to the console during a propagation, are to be provided as a floating point value. To enable all console printing that can be defined by a boolean, the :meth:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.enable_all_printing` function can be used. To disable *all* console printing, us the :meth:`~tudatpy.dynamics.propagation_setup.propagator.PropagationPrintSettings.disable_all_printing` function. An example of defining console output is: .. code-block:: python propagator_settings = propagator.translational( ... ) console_print_settings = propagator_settings.print_settings console_print_settings.print_state_indices = True console_print_settings.print_dependent_variable_indices = True console_print_settings.print_propagation_clock_time = True console_print_settings.print_termination_reason = True console_print_settings.print_number_of_function_evaluations = True which will result in the following terminal output (for a specific script propagating dynamics of Delfi C-3 w.r.t. Earth):: =============== STARTING SINGLE-ARC PROPAGATION =============== PROCESSED STATE VECTOR CONTENTS: [Vector entries], content description [0:5], Translational state of body Delfi-C3 w.r.t. Earth DEPENDENT VARIABLE VECTOR CONTENTS: [Vector entries], content description [0:2], Total acceleration in inertial frame of Delfi-C3 [3:8], Kepler elements of Delfi-C3 w.r.t. Earth PROPAGATION FINISHED. Total Number of Function Evaluations: 43201 Total propagation clock time: 2.94223 seconds Termination reason: Propagation successful; termination condition exceeded ================================================================= .. _console_output_multi_arc: Multi- and hybrid-arc console output ------------------------------------ For the multi- and hybrid arc simulations, the console output is specified in its constituent single-arc propagation settings where, in principle, these settings can be different for each arc, and are processed independently. However, a number of additional options are available for printing output to the console for multi- and hybrid-arc propagation, in the :class:`~tudatpy.dynamics.propagation_setup.propagator.MultiArcPropagatorProcessingSettings` and :class:`~tudatpy.dynamics.propagation_setup.propagator.HybridArcPropagatorProcessingSettings` classes: * For the multi- and hybrid arc propagation, there is an option to ensure identical print settings for each arc (see :attr:`~tudatpy.dynamics.propagation_setup.propagator.MultiArcPropagatorProcessingSettings.set_print_settings_for_all_arcs`) * For the multi-arc propagation, there is an option to automatically suppress all output for all arcs *except* the first arc (see :attr:`~tudatpy.dynamics.propagation_setup.propagator.MultiArcPropagatorProcessingSettings.print_output_on_first_arc_only`) This is typically used in cases where the settings for each arc are largely identical * For the hybrid-arc propagation, the constituent single- and multi-arc settings can be independently modified. These settings can be extracted from the :attr:`~tudatpy.dynamics.propagation_setup.propagator.HybridArcPropagatorProcessingSettings.single_arc_settings` and :attr:`~tudatpy.dynamics.propagation_setup.propagator.HybridArcPropagatorProcessingSettings.multi_arc_settings` attributes.