Skip to content

ENH: change verbose prints to log in python. #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 17, 2024
Merged
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
103 changes: 63 additions & 40 deletions open_rocket_serializer/cli.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import json
import logging
import os
from pathlib import Path

import click
import orhelper
from bs4 import BeautifulSoup
from orhelper import OrLogLevel

from ._helpers import extract_ork_from_zip, parse_ork_file
from .ork_extractor import ork_extractor

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%Y.%b.%d %H:%M:%S",
filename="serializer.log",
filemode="w",
)
logger = logging.getLogger(__name__)

# define the logger handler for the console (useful for the command line interface)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
console.setFormatter(formatter)
logger.addHandler(console)


@click.group()
@click.version_option()
@@ -44,9 +63,11 @@ def cli():


@cli.command("ork2json")
@click.option("--filepath", type=str, required=True, help="The path to the .ork file.")
@click.option(
"--output", type=str, required=False, help="The path to the output folder."
"--filepath", type=click.Path(), required=True, help="The path to the .ork file."
)
@click.option(
"--output", type=click.Path(), required=False, help="The path to the output folder."
)
@click.option(
"--eng",
@@ -57,7 +78,7 @@ def cli():
)
@click.option(
"--ork_jar",
type=str,
type=click.Path(),
default=None,
required=False,
help="The path to the OpenRocket .jar file.",
@@ -95,37 +116,39 @@ def ork2json(filepath, output=None, eng=None, ork_jar=None, verbose=False):
--------
>>> serializer ork2json("rocket.ork", "rocket", "motor.eng")
"""
log_level = logging.DEBUG if verbose else logging.WARNING
logger.setLevel(log_level)

# first check if the file exists
if os.path.exists(filepath) is False:
raise ValueError(
"The .ork file does not exist.\n" + "Please specify a valid path."
)
filepath = Path(filepath)

try:
bs = BeautifulSoup(open(filepath, encoding="utf-8").read(), features="xml")
except UnicodeDecodeError:
raise ValueError(
"The .ork file is not in UTF-8.\n"
+ "Please open the .ork file in a text editor and save it as UTF-8."
+ "Also, you should check if your .ork file is really a xml file or "
+ "a zip file. If it is a zip file, you should unzip it first."
)
if not filepath.exists():
error = "[ork2json] The .ork file or zip archive does not exist. Please specify a valid path."
logger.error(error)
raise FileNotFoundError(error)

datapoints = bs.findAll("datapoint")
if filepath.suffix.lower() == ".ork":
extract_dir = filepath.parent
filepath = extract_ork_from_zip(filepath, extract_dir)
logger.info(f"[ork2json] Extracted .ork file to: '{filepath.as_posix()}'")

bs, datapoints = parse_ork_file(filepath)

if len(datapoints) == 0:
raise ValueError(
"The file must contain the simulation data.\n"
error_msg = (
"[ork2json] The file must contain the simulation data.\n"
+ "Open the .ork file and run the simulation first."
)
logger.error(error_msg)
raise ValueError(error_msg)

data_labels = bs.find("databranch").attrs["types"].split(",")
if "CG location" not in data_labels:
raise ValueError(
"The file must be in English.\n"
+ "Open the .ork file and change the language to English."
message = (
"[ork2json] The file must contain the simulation data.\n"
+ "Open the .ork file and run the simulation first."
)
logger.error(message)
raise ValueError(message)

if not ork_jar:
# get any .jar file in the current directory that starts with "OpenRocket"
@@ -134,49 +157,51 @@ def ork2json(filepath, output=None, eng=None, ork_jar=None, verbose=False):
]
if len(ork_jar) == 0:
raise ValueError(
"It was impossible to find the OpenRocket .jar file in the current directory.\n"
"[ork2json] It was impossible to find the OpenRocket .jar file in the current directory.\n"
+ "Please specify the path to the .jar file."
)
ork_jar = ork_jar[0]
# print to the user that the .jar file was found, and show the name of the file
if verbose:
print(f"[ork2json] Found OpenRocket .jar file: {ork_jar}")
logger.info(
f"[ork2json] Found OpenRocket .jar file: '{Path(ork_jar).as_posix()}'"
)

if not output:
# get the same folder as the .ork file
output = os.path.dirname(filepath)
if verbose:
print(f"[ork2json] Output folder not specified. Using {output} instead.")
logger.warning(
f"[ork2json] Output folder not specified. Using '{Path(output).as_posix()}' instead."
)

# orhelper options are: OFF, ERROR, WARN, INFO, DEBUG, TRACE and ALL
log_level = "OFF" if verbose else "OFF"
# log_level = "OFF" if verbose else "OFF"
# TODO: even if the log level is set to OFF, the orhelper still prints msgs

with orhelper.OpenRocketInstance(ork_jar, log_level=log_level) as instance:
with orhelper.OpenRocketInstance(ork_jar, log_level="OFF") as instance:
# create the output folder if it does not exist
if os.path.exists(output) is False:
os.mkdir(output)

orh = orhelper.Helper(instance)
ork = orh.load_doc(filepath)
ork = orh.load_doc(str(filepath))

settings = ork_extractor(
bs=bs,
filepath=filepath,
filepath=str(filepath),
output_folder=output,
ork=ork,
eng=eng,
verbose=verbose,
)

with open(os.path.join(output, "parameters.json"), "w") as convert_file:
convert_file.write(
json.dumps(settings, indent=4, sort_keys=True, ensure_ascii=False)
)
if verbose:
print(f"[ork2json] parameters.json file saved in {output}")

return None
logger.info(
f"[ork2json] The file 'parameters.json' was saved to: '{Path(output).as_posix()}'"
)
logger.info(
f"[ork2json] Operation completed successfully. You can now use the 'parameters.json' file to run a simulation."
)


@cli.command("ork2py")
@@ -209,7 +234,6 @@ def ork2py(
_description_
"""
get_dict = ork2json(filepath, output, eng, ork_jar)
return None


@cli.command("ork2ipynb")
@@ -219,4 +243,3 @@ def ork2py(
@click.option("--ork_jar", type=str, default=None, required=False)
def ork2ipynb(filepath, output, eng=None, ork_jar=None):
get_dict = ork2json(filepath, output, eng, ork_jar)
return None
18 changes: 11 additions & 7 deletions open_rocket_serializer/components/drag_curve.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import logging
import os
from pathlib import Path

import numpy as np

logger = logging.getLogger(__name__)

def save_drag_curve(datapoints, data_labels, output_folder, verbose=False):

def save_drag_curve(datapoints, data_labels, output_folder):
"""Extracts the drag curve from the data and saves it to a csv file.

Parameters
@@ -15,9 +19,6 @@ def save_drag_curve(datapoints, data_labels, output_folder, verbose=False):
path : str
Path to the folder where the drag curve should be saved. This needs to
be a folder that already exists.
verbose : bool, optional
Whether or not to print a message of successful execution, by default
False.

Returns
-------
@@ -29,8 +30,11 @@ def save_drag_curve(datapoints, data_labels, output_folder, verbose=False):
float(datapoint.text.split(",")[data_labels.index("Altitude")])
for datapoint in datapoints
]
logger.info(f"Collected altitude vector")

apogee_index = np.argmax(altitude_vector)
datapoints = datapoints[:apogee_index]
logger.info(f"Removed data after apogee")

# Extract the drag coefficient and Mach number
cd = [
@@ -41,6 +45,7 @@ def save_drag_curve(datapoints, data_labels, output_folder, verbose=False):
float(datapoint.text.split(",")[data_labels.index("Mach number")])
for datapoint in datapoints
]
logger.info(f"Collected drag coefficient and Mach number")

# Convert to numpy array
cd = np.array([mach, cd]).T
@@ -52,11 +57,10 @@ def save_drag_curve(datapoints, data_labels, output_folder, verbose=False):
cd = np.unique(cd, axis=0)
# Remove values when the drag is lower than 0
cd = cd[cd[:, 1] > 0, :]
logger.info(f"Successfully created the drag curve")

# Save to csv file
path = os.path.join(output_folder, "drag_curve.csv")
np.savetxt(path, cd, delimiter=",", fmt="%.6f")

if verbose:
print(f"[Drag Curve] Successfully extracted the drag curve: {path}")
logger.info(f"Successfully saved the drag curve file to: '{Path(path).as_posix()}'")
return path
40 changes: 31 additions & 9 deletions open_rocket_serializer/components/environment.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import logging

import yaml

from .._helpers import _dict_to_string

logger = logging.getLogger(__name__)

def search_environment(bs, verbose=False):

def search_environment(bs):
"""Searches the launch conditions in the bs object. Returns a dict with the
settings.

Parameters
----------
bs : BeautifulSoup
BeautifulSoup object of the .ork file.
verbose : bool, optional
Whether or not to print a message of successful execution, by default
False.

Returns
-------
@@ -28,13 +31,33 @@ def search_environment(bs, verbose=False):
wind_average = float(bs.find("windaverage").text)
wind_turbulence = float(bs.find("windturbulence").text)
geodetic_method = bs.find("geodeticmethod").text
logger.info(
"Collected first environment settings: latitude, "
+ "longitude, elevation, wind_average, wind_turbulence, geodetic_method"
)
try:
base_temperature = float(bs.find("basetemperature").text)
logger.info(
"The base temperature was found in the .ork file. "
+ f"It is {base_temperature} °C."
)
except AttributeError:
logger.warning(
"No base temperature was found in the .ork file. "
+ "The base temperature will be set to None."
)
base_temperature = None
try:
base_pressure = float(bs.find("basepressure").text)
logger.info(
"The base pressure was found in the .ork file. "
+ f"It is {base_pressure} Pa."
)
except AttributeError:
logger.warning(
"No base pressure was found in the .ork file. "
+ "The base pressure will be set to None."
)
base_pressure = None
date = None

@@ -49,9 +72,8 @@ def search_environment(bs, verbose=False):
"base_pressure": base_pressure,
"date": date,
}
if verbose:
print(
f"[Environment] The environment settings were extracted."
+ f" \n{yaml.dump(settings, default_flow_style=False)}"
)
logger.info(
"Successfully extracted all the environment settings.\n"
+ _dict_to_string(settings, indent=23)
)
return settings
Loading