From ed043e7929e1d144e1ec8c08857400091c52805f Mon Sep 17 00:00:00 2001 From: Pedro Bressan Date: Mon, 21 Apr 2025 14:15:30 +0200 Subject: [PATCH] BUG: Fix the handling of reference pressure for older rpy files. --- CHANGELOG.md | 1 + rocketpy/_encoders.py | 104 ++++++++++++++++------------- rocketpy/motors/hybrid_motor.py | 2 +- rocketpy/motors/liquid_motor.py | 2 +- rocketpy/motors/motor.py | 2 +- rocketpy/motors/solid_motor.py | 2 +- rocketpy/simulation/monte_carlo.py | 10 ++- rocketpy/utilities.py | 12 ++-- tests/unit/test_utilities.py | 2 +- 9 files changed, 79 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4b7a9fd2..68bcce140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Attention: The newest changes should be on top --> ### Fixed +- BUG: Fix the handling of reference pressure for older rpy files. [#808](https://github.com/RocketPy-Team/RocketPy/pull/808) ## v1.9.0 - 2025-03-24 diff --git a/rocketpy/_encoders.py b/rocketpy/_encoders.py index e24bb1a8a..141ff6baa 100644 --- a/rocketpy/_encoders.py +++ b/rocketpy/_encoders.py @@ -7,8 +7,8 @@ import numpy as np from rocketpy.mathutils.function import Function -from rocketpy.prints.flight_prints import _FlightPrints from rocketpy.plots.flight_plots import _FlightPlots +from rocketpy.prints.flight_prints import _FlightPrints class RocketPyEncoder(json.JSONEncoder): @@ -91,50 +91,7 @@ def object_hook(self, obj): new_flight = class_.__new__(class_) new_flight.prints = _FlightPrints(new_flight) new_flight.plots = _FlightPlots(new_flight) - attributes = ( - "rocket", - "env", - "rail_length", - "inclination", - "heading", - "initial_solution", - "terminate_on_apogee", - "max_time", - "max_time_step", - "min_time_step", - "rtol", - "atol", - "time_overshoot", - "name", - "solution", - "out_of_rail_time", - "apogee_time", - "apogee", - "parachute_events", - "impact_state", - "impact_velocity", - "x_impact", - "y_impact", - "t_final", - "flight_phases", - "ax", - "ay", - "az", - "out_of_rail_time_index", - "function_evaluations", - "alpha1", - "alpha2", - "alpha3", - "R1", - "R2", - "R3", - "M1", - "M2", - "M3", - ) - for attribute in attributes: - setattr(new_flight, attribute, obj[attribute]) - new_flight.t_initial = new_flight.initial_solution[0] + set_minimal_flight_attributes(new_flight, obj) return new_flight elif hasattr(class_, "from_dict"): return class_.from_dict(obj) @@ -153,6 +110,63 @@ def object_hook(self, obj): return obj +def set_minimal_flight_attributes(flight, obj): + attributes = ( + "rocket", + "env", + "rail_length", + "inclination", + "heading", + "initial_solution", + "terminate_on_apogee", + "max_time", + "max_time_step", + "min_time_step", + "rtol", + "atol", + "time_overshoot", + "name", + "solution", + "out_of_rail_time", + "apogee_time", + "apogee", + "parachute_events", + "impact_state", + "impact_velocity", + "x_impact", + "y_impact", + "t_final", + "flight_phases", + "ax", + "ay", + "az", + "out_of_rail_time_index", + "function_evaluations", + "speed", + "alpha1", + "alpha2", + "alpha3", + "R1", + "R2", + "R3", + "M1", + "M2", + "M3", + "net_thrust", + ) + + for attribute in attributes: + try: + setattr(flight, attribute, obj[attribute]) + except KeyError: + # Manual resolution of new attributes + if attribute == "net_thrust": + flight.net_thrust = obj["rocket"].motor.thrust + flight.net_thrust.set_discrete_based_on_model(flight.speed) + + flight.t_initial = flight.initial_solution[0] + + def get_class_signature(obj): """Returns the signature of a class so it can be identified on decoding. The signature is a dictionary with the module and diff --git a/rocketpy/motors/hybrid_motor.py b/rocketpy/motors/hybrid_motor.py index 1de9f435c..e227e4550 100644 --- a/rocketpy/motors/hybrid_motor.py +++ b/rocketpy/motors/hybrid_motor.py @@ -699,7 +699,7 @@ def from_dict(cls, data): grains_center_of_mass_position=data["grains_center_of_mass_position"], nozzle_position=data["nozzle_position"], throat_radius=data["throat_radius"], - reference_pressure=data["reference_pressure"], + reference_pressure=data.get("reference_pressure"), ) for tank in data["positioned_tanks"]: diff --git a/rocketpy/motors/liquid_motor.py b/rocketpy/motors/liquid_motor.py index 5edaae3b8..acce874af 100644 --- a/rocketpy/motors/liquid_motor.py +++ b/rocketpy/motors/liquid_motor.py @@ -528,7 +528,7 @@ def from_dict(cls, data): nozzle_position=data["nozzle_position"], interpolation_method=data["interpolate"], coordinate_system_orientation=data["coordinate_system_orientation"], - reference_pressure=data["reference_pressure"], + reference_pressure=data.get("reference_pressure"), ) for tank in data["positioned_tanks"]: diff --git a/rocketpy/motors/motor.py b/rocketpy/motors/motor.py index ebc39b05a..7178cdcf5 100644 --- a/rocketpy/motors/motor.py +++ b/rocketpy/motors/motor.py @@ -1896,5 +1896,5 @@ def from_dict(cls, data): ), nozzle_position=data["nozzle_position"], interpolation_method=data["interpolate"], - reference_pressure=data["reference_pressure"], + reference_pressure=data.get("reference_pressure"), ) diff --git a/rocketpy/motors/solid_motor.py b/rocketpy/motors/solid_motor.py index e736831bb..a8d823966 100644 --- a/rocketpy/motors/solid_motor.py +++ b/rocketpy/motors/solid_motor.py @@ -821,5 +821,5 @@ def from_dict(cls, data): throat_radius=data["throat_radius"], interpolation_method=data["interpolate"], coordinate_system_orientation=data["coordinate_system_orientation"], - reference_pressure=data["reference_pressure"], + reference_pressure=data.get("reference_pressure"), ) diff --git a/rocketpy/simulation/monte_carlo.py b/rocketpy/simulation/monte_carlo.py index f5f79bd17..25531fc9a 100644 --- a/rocketpy/simulation/monte_carlo.py +++ b/rocketpy/simulation/monte_carlo.py @@ -281,6 +281,7 @@ def __run_in_serial(self): try: while sim_monitor.keep_simulating(): sim_monitor.increment() + inputs_json, outputs_json = "", "" flight = self.__run_single_simulation() inputs_json = self.__evaluate_flight_inputs(sim_monitor.count) @@ -406,6 +407,7 @@ def __sim_producer(self, seed, sim_monitor, mutex, error_event): # pylint: disa while sim_monitor.keep_simulating(): sim_idx = sim_monitor.increment() - 1 + inputs_json, outputs_json = "", "" flight = self.__run_single_simulation() inputs_json = self.__evaluate_flight_inputs(sim_idx) @@ -484,7 +486,9 @@ def __evaluate_flight_inputs(self, sim_idx): for item in d.items() ) inputs_dict["index"] = sim_idx - return json.dumps(inputs_dict, cls=RocketPyEncoder) + "\n" + return ( + json.dumps(inputs_dict, cls=RocketPyEncoder, **self._export_config) + "\n" + ) def __evaluate_flight_outputs(self, flight, sim_idx): """Evaluates the outputs of a single flight simulation. @@ -518,7 +522,9 @@ def __evaluate_flight_outputs(self, flight, sim_idx): ) from e outputs_dict = outputs_dict | additional_exports - return json.dumps(outputs_dict, cls=RocketPyEncoder) + "\n" + return ( + json.dumps(outputs_dict, cls=RocketPyEncoder, **self._export_config) + "\n" + ) def __terminate_simulation(self): """ diff --git a/rocketpy/utilities.py b/rocketpy/utilities.py index 1bb8f22a0..06e0582eb 100644 --- a/rocketpy/utilities.py +++ b/rocketpy/utilities.py @@ -1,23 +1,23 @@ import ast import inspect -import traceback -import warnings import json import os - -from pathlib import Path -from importlib.metadata import version +import traceback +import warnings from datetime import date +from importlib.metadata import version +from pathlib import Path + import matplotlib.pyplot as plt import numpy as np from scipy.integrate import solve_ivp +from ._encoders import RocketPyDecoder, RocketPyEncoder from .environment.environment import Environment from .mathutils.function import Function from .plots.plot_helpers import show_or_save_plot from .rocket.aero_surface import TrapezoidalFins from .simulation.flight import Flight -from ._encoders import RocketPyEncoder, RocketPyDecoder def compute_cd_s_from_drop_test( diff --git a/tests/unit/test_utilities.py b/tests/unit/test_utilities.py index cec24cdba..55d45de95 100644 --- a/tests/unit/test_utilities.py +++ b/tests/unit/test_utilities.py @@ -1,6 +1,6 @@ +import os from unittest.mock import patch -import os import numpy as np import pytest