Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,34 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also export our Monte Carlo results into .csv and .json files using the method `MonteCarlo.export_results()`.\n",
"\n",
"Choose a name for the output file and select a format to output."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Results saved to monte_carlo_analysis_outputs/monte_carlo_csv_output_example as .csv file\n",
"Results saved to monte_carlo_analysis_outputs/monte_carlo_json_output_example as .json file\n"
]
}
],
"source": [
"test_dispersion.export_results(\"monte_carlo_analysis_outputs/monte_carlo_csv_output_example\", \"csv\")\n",
"test_dispersion.export_results(\"monte_carlo_analysis_outputs/monte_carlo_json_output_example\", \"json\")"
]
},
{
"attachments": {},
"cell_type": "markdown",
Expand Down
36 changes: 36 additions & 0 deletions rocketpy/simulation/monte_carlo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""

import json
import csv
import os
import traceback
import warnings
Expand Down Expand Up @@ -588,6 +589,41 @@ def __evaluate_flight_outputs(self, flight, sim_idx):
json.dumps(outputs_dict, cls=RocketPyEncoder, **self._export_config) + "\n"
)

def export_results(self, output_filename, output_format):
"""Converts the default Monte Carlo .txt output to .cvs or .json file
depending on the user's choice

Parameters
----------
output_filename : str
Name of the file in which the converted data will be saved
output_format : str
Format of the output file

Returns
-------
None
"""
txt_data = []
with open(f"{self.filename}.outputs.txt", "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
data = json.loads(line)
txt_data.append(data)

output_format = output_format.strip().lower()
if output_format == "json":
with open(f"{output_filename}.json", "w", encoding="utf-8") as f:
json.dump(txt_data, f, indent=4)
_SimMonitor.reprint(f"Results saved to {Path(output_filename)} as .json file")
elif output_format == "csv":
output_csv_header = txt_data[0].keys()
with open(f"{output_filename}.csv", "w", newline= "") as f:
output_writer = csv.DictWriter(f, fieldnames=output_csv_header)
output_writer.writeheader()
output_writer.writerows(txt_data)
_SimMonitor.reprint(f"Results saved to {Path(output_filename)} as .csv file")

def __terminate_simulation(self):
"""
Terminates the simulation, closes the files and prints the results.
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/simulation/test_monte_carlo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import matplotlib as plt
import numpy as np
import pytest
import json
import os

from rocketpy.simulation import MonteCarlo

Expand Down Expand Up @@ -185,3 +187,31 @@ def test_estimate_confidence_interval_raises_type_error_for_invalid_statistic():

with pytest.raises(TypeError):
mc.estimate_confidence_interval("apogee", statistic="not_a_function")


def test_monte_carlo_export_results_to_csv_and_json_files(monte_carlo_calisto, tmp_path):
"""Checks that the export_results create .csv and .json files

Parameters
----------
monte_carlo_calisto : MonteCarlo
Fixture that has the .txt files necessary for the export_results
"""
try:
mc = monte_carlo_calisto
mc.filename = tmp_path / "mock_output"
mock_data = {"apogee": 100, "max_velocity": 255}
with open(tmp_path / "mock_output.outputs.txt", "w") as f:
f.write(json.dumps(mock_data) + "\n")

mc.export_results(tmp_path / "mock_outputs_in_csv", "csv")
expected_file_in_csv = tmp_path / f"{"mock_outputs_in_csv"}.csv"
assert expected_file_in_csv.exists()

mc.export_results(tmp_path / "mock_output_in_json", "json")
expected_file_in_json = tmp_path / f"{"mock_output_in_json"}.json"
assert expected_file_in_json.exists()
finally:
os.remove("monte_carlo_test.errors.txt")
os.remove("monte_carlo_test.inputs.txt")
os.remove("monte_carlo_test.outputs.txt")