CCR/.venv/lib/python3.12/site-packages/pysd/cli/main.py

148 lines
4.3 KiB
Python

import sys
import os
from pathlib import Path
from datetime import datetime
import pysd
from pysd.translators.vensim.vensim_utils import supported_extensions as\
vensim_extensions
from pysd.translators.xmile.xmile_utils import supported_extensions as\
xmile_extensions
from .parser import parser
def main(args):
"""
Main function. Reads user arguments, loads the models,
runs it and saves the output
Parameters
----------
args: list
User arguments.
Returns
-------
None
"""
options = parser.parse_args(args)
model = load(options.model_file, options.data_files,
options.missing_values, options.split_views,
subview_sep=options.subview_sep)
if not options.run:
print("\nFinished!")
sys.exit()
model.initialize()
if not options.output_file:
options.output_file = os.path.splitext(os.path.basename(
options.model_file
))[0]\
+ datetime.now().strftime("_output_%Y_%m_%d-%H_%M_%S_%f.tab")
model.run(**create_configuration(model, options))
if options.export_file:
model.export(options.export_file)
print("\nFinished!")
sys.exit()
def load(model_file, data_files, missing_values, split_views, **kwargs):
"""
Translate and load model file.
Paramters
---------
model_file: str
Vensim, Xmile or PySD model file.
data_files: list
If given the list of files where the necessary data to run the model
is given.
missing_values : str ("warning", "error", "ignore", "keep")
What to do with missing values. If "warning" (default)
shows a warning message and interpolates the values.
If "raise" raises an error. If "ignore" interpolates
the values without showing anything. If "keep" it will keep
the missing values, this option may cause the integration to
fail, but it may be used to check the quality of the data.
split_views: bool (optional)
If True, the sketch is parsed to detect model elements in each
model view, and then translate each view in a separate Python
file. Setting this argument to True is recommended for large
models split in many different views. Default is False.
**kwargs: (optional)
Additional keyword arguments.
subview_sep:(str)
Character used to separate views and subviews. If provided,
and split_views=True, each submodule will be placed inside the
folder of the parent view.
Returns
-------
pysd.model
"""
model_file_suffix = Path(model_file).suffix.lower()
if model_file_suffix in vensim_extensions:
print("\nTranslating model file...\n")
return pysd.read_vensim(model_file, initialize=False,
data_files=data_files,
missing_values=missing_values,
split_views=split_views, **kwargs)
elif model_file_suffix in xmile_extensions:
print("\nTranslating model file...\n")
return pysd.read_xmile(model_file, initialize=False,
data_files=data_files,
missing_values=missing_values)
else:
return pysd.load(model_file, initialize=False,
data_files=data_files,
missing_values=missing_values)
def create_configuration(model, options):
"""
create configuration dict to pass to the run method.
Parameters
----------
model: pysd.model object
options: argparse.Namespace
Returns
-------
conf_dict: dict
"""
conf_dict = {
"progress": options.progress,
"params": options.new_values["param"],
"initial_condition": (options.initial_time or model.time(),
options.new_values["initial"]),
"return_columns": options.return_columns,
"final_time": options.final_time,
"time_step": options.time_step,
"saveper": options.saveper,
"flatten_output": True, # need to return totally flat DF
"return_timestamps": options.return_timestamps, # given or None,
"output_file": options.output_file
}
if options.import_file:
conf_dict["initial_condition"] = options.import_file
return conf_dict