import importlib.util
import logging
from pathlib import Path
from .meta_optimization_problem import MetaOptimizationProblem
from .meta_mixin import MetaMixin
logger = logging.getLogger("rtctools")
[docs]def collect_model_instance(model_name: str, module_path: str, base_folder: str = ".."):
"""Collect an object from a python file anywhere in your file system
:param model_name: Name of the model that you want to collect and instantiate
:param module_path: Path to the file where the model is defined
:param base_folder: Path to the base folder of the model. Default is ``".."``
:raises: AssertionError
"""
# Resolve module path
module_path = Path(module_path).resolve()
assert module_path.is_file(), f"Path {module_path} is not valid."
# Load model
spec = importlib.util.spec_from_file_location(f"{module_path.stem}", module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
Model = getattr(module, model_name)
# Instantiate Model
if issubclass(Model, MetaOptimizationProblem):
return Model()
elif issubclass(Model, MetaMixin):
# Check for some common mistakes in inheritance order
# TODO: Need OrderedSet or a different approach
# suggested_order = OrderedSet(
# [
# "MetaMixin",
# "HomotopyMixin",
# "GoalProgrammingMixin",
# "PIMixin",
# "CSVMixin",
# "ModelicaMixin",
# "ControlTreeMixin",
# "CollocatedIntegratedOptimizationProblem",
# "OptimizationProblem",
# ]
# )
# base_names = OrderedSet([b.__name__ for b in Model.__bases__])
# if suggested_order & base_names != base_names & suggested_order:
# msg = (
# f"{Model.__name__}: Please inherit from base classes in the "
# f"following order: {list(base_names & suggested_order)}"
# )
# logger.error(msg)
# raise Exception(msg)
# Collect instantiation parameters
base_folder = (module_path.parent / base_folder).resolve()
input_folder = base_folder / "input"
model_folder = base_folder / "model"
output_folder = base_folder / "output"
# Assert directories actually exist
for directory in (input_folder, model_folder, output_folder):
assert directory.is_dir(), f"Path {directory} does not exist."
# Return an instance of Model
return Model(
input_folder=input_folder,
model_folder=model_folder,
output_folder=output_folder,
)
else:
raise Exception(f"{model_name} in {module_path} is not a model or metamodel.")