Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-28 07:12:52

0001 """Full configuration loader - combines problem and optimization payloads."""
0002 
0003 from pathlib import Path
0004 from typing import Dict, Optional, Any
0005 
0006 import yaml
0007 from pydantic import BaseModel
0008 
0009 from .problem_config import ProblemConfiguration, ProblemConfigLoader
0010 from .optimization_config import OptimizationConfiguration
0011 
0012 
0013 class FullConfig(BaseModel):
0014     """Complete configuration combining problem and optimization."""
0015     problem: ProblemConfiguration
0016     optimization: OptimizationConfiguration
0017 
0018 
0019 def _normalize_full_config_data(data: Dict[str, Any], config_path: Path) -> Dict[str, Any]:
0020     """Normalize loosely structured YAML into a FullConfig-friendly dict."""
0021     if "problem" not in data:
0022         raise ValueError("Config must contain a 'problem' section")
0023 
0024     base_dir = config_path.parent
0025     problem_raw = dict(data.get("problem", {}))
0026 
0027     type_val = problem_raw.get("type") or problem_raw.get("problem_type") or ""
0028     problem_raw["type"] = type_val
0029     problem_raw["problem_type"] = type_val
0030 
0031     problem_raw.setdefault("output_location", str(base_dir / "output"))
0032     problem_raw.setdefault("work_location", str(base_dir / "work"))
0033 
0034     if "design_parameters_file" not in problem_raw:
0035         design_space = problem_raw.get("design_space") or {}
0036         if isinstance(design_space, dict) and design_space.get("path"):
0037             problem_raw["design_parameters_file"] = design_space["path"]
0038 
0039     if "design_space" in problem_raw:
0040         problem_raw.pop("design_space", None)
0041 
0042     problem_cfg = ProblemConfigLoader.from_dict(problem_raw, base_dir=str(base_dir))
0043 
0044     if "optimization" in data:
0045         opt_cfg = OptimizationConfiguration(**data["optimization"])
0046     else:
0047         optimizer_block = data.get("optimizer", {})
0048         objectives_raw = problem_raw.get("objectives", [])
0049         bo_params = optimizer_block.get("bo", {}).get("parameters", {}) if isinstance(optimizer_block, dict) else {}
0050         opt_cfg = OptimizationConfiguration(
0051             name=data.get("metadata", {}).get("project", "optimization"),
0052             description=data.get("metadata", {}).get("description", ""),
0053             optimizer={
0054                 "name": optimizer_block.get("kind", ""),
0055                 "type": optimizer_block.get("kind", ""),
0056                 "parameters": bo_params,
0057             },
0058             objectives=[
0059                 f"{'minimize' if obj.get('minimize', True) else 'maximize'}:{obj['name']}"
0060                 for obj in objectives_raw
0061                 if isinstance(obj, dict) and "name" in obj
0062             ],
0063             constraints=[],
0064             n_iterations=optimizer_block.get("max_iterations", 0),
0065             n_initial_samples=bo_params.get("n_initial_samples", 0),
0066             parallel_evaluations=bo_params.get("parallel_evaluations", 1),
0067         )
0068 
0069     return {"problem": problem_cfg, "optimization": opt_cfg}
0070 
0071 
0072 def load_config(config_file: str) -> FullConfig:
0073     """
0074     Load complete configuration from a YAML file.
0075     
0076     Args:
0077         config_file: Path to YAML configuration file
0078         
0079     Returns:
0080         FullConfig object with all configurations loaded
0081         
0082     Raises:
0083         FileNotFoundError: If config file doesn't exist
0084         ValueError: If configuration is invalid
0085     """
0086     config_path = Path(config_file)
0087     
0088     if not config_path.exists():
0089         raise FileNotFoundError(f"Config file not found: {config_file}")
0090     
0091     with open(config_path, 'r') as f:
0092         data = yaml.safe_load(f)
0093 
0094     normalized = _normalize_full_config_data(data or {}, config_path)
0095 
0096     return FullConfig(**normalized)