From f9014259f7974a46c733465dcabc74e3a3b6bb7b Mon Sep 17 00:00:00 2001 From: Mohcine Chraibi Date: Tue, 29 Oct 2024 08:06:46 +0100 Subject: [PATCH] Fix CI --- generage_variations.py | 69 +++++++++++++++++++++++------------------- simulation.py | 29 +++++++++--------- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/generage_variations.py b/generage_variations.py index dee4459..ae33715 100644 --- a/generage_variations.py +++ b/generage_variations.py @@ -1,3 +1,5 @@ +"""Generate variation files necessary to start simulations.""" + import json import logging import pathlib @@ -5,61 +7,66 @@ import typer from datetime import datetime -def get_nested_value(config: Dict, param_path: str) -> Any: + +def get_nested_value(config: Dict[str, Any], param_path: str) -> Any: """Get value from nested dictionary using dot notation.""" - keys = param_path.split('/') + keys = param_path.split("/") current = config for key in keys: current = current[key] return current -def set_nested_value(config: Dict, param_path: str, value: Any) -> None: + +def set_nested_value(config: Dict[str, Any], param_path: str, value: Any) -> None: """Set value in nested dictionary using dot notation.""" - keys = param_path.split('/') + keys = param_path.split("/") current = config for key in keys[:-1]: current = current[key] current[keys[-1]] = value + def create_parameter_variations( - base_config: Dict, + base_config: Dict[str, Any], param_path: str, - values: List[Union[float, int, str]], - description: str = "" -) -> List[Dict]: + values: List[Union[float, int]], + description: str = "", +) -> List[Dict[str, Any]]: """ Create variations of the configuration by varying a single parameter. - + Args: base_config: The base configuration dictionary param_path: Path to the parameter using '/' notation (e.g., 'motivation_parameters/height') values: List of values to try for this parameter description: Optional description of what these variations represent - + Returns: List of variation dictionaries """ original_value = get_nested_value(base_config, param_path) variations = [] - + for value in values: variation = { "name": f"{param_path.replace('/', '_')}_{value}", "description": description, "original_value": original_value, - "parameters": { - param_path: value - } + "parameters": {param_path: value}, } variations.append(variation) - + return variations -def save_variations(variations: List[Dict], output_path: pathlib.Path) -> None: + +def save_variations( + variations: List[Dict[str, Any]], output_path: pathlib.Path +) -> None: """Save variations to a JSON file with proper formatting.""" with open(output_path, "w", encoding="utf8") as f: json.dump(variations, f, indent=4) + def main( inifile: pathlib.Path = typer.Option( pathlib.Path("files/inifile.json"), @@ -85,22 +92,24 @@ def main( """Generate parameter variations for simulation runs.""" if not param or not values: print("Usage example:") - print(" python generate_variations.py --inifile files/inifile.json \\\n" - " --param motivation_parameters/height \\\n" - " --values 0.5,1.0,1.5 \\\n" - " --description 'Testing different heights'") + print( + " python generate_variations.py --inifile files/inifile.json \\\n" + " --param motivation_parameters/height \\\n" + " --values 0.5,1.0,1.5 \\\n" + " --description 'Testing different heights'" + ) return # Load base configuration with open(inifile, "r", encoding="utf8") as f: base_config = json.load(f) - + # Parse values (handle both float and int) try: - parsed_values = [] - for v in values.split(','): + parsed_values: List[float | int] = [] + for v in values.split(","): v = v.strip() - if '.' in v: + if "." in v: parsed_values.append(float(v)) else: parsed_values.append(int(v)) @@ -110,18 +119,15 @@ def main( # Generate variations variations = create_parameter_variations( - base_config, - param, - parsed_values, - description + base_config, param, parsed_values, description ) - + # Determine output path if output is None: - param_name = param.replace('/', '_') + param_name = param.replace("/", "_") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output = pathlib.Path(f"variations_{param_name}_{timestamp}.json") - + # Save variations save_variations(variations, output) print(f"Created {len(variations)} variations in {output}") @@ -129,5 +135,6 @@ def main( for var in variations: print(f"- {var['name']}: {var['parameters'][param]}") + if __name__ == "__main__": typer.run(main) diff --git a/simulation.py b/simulation.py index b19b8c9..325b25f 100644 --- a/simulation.py +++ b/simulation.py @@ -183,7 +183,7 @@ def init_simulation( output_file=pathlib.Path(_trajectory_path), every_nth_frame=_fps ), ) - logging.info("Init simulation done") + logging.info("Init simulation done.") return simulation @@ -512,7 +512,7 @@ def start_simulation(config_path: str, output_path: str) -> float: return evac_time -def load_variations(variations_path: pathlib.Path) -> List[Dict]: +def load_variations(variations_path: pathlib.Path) -> List[Dict[str, Any]]: """Load parameter variations from a JSON file.""" if not variations_path.exists(): raise FileNotFoundError(f"Variations file not found: {variations_path}") @@ -529,7 +529,7 @@ def load_variations(variations_path: pathlib.Path) -> List[Dict]: def modify_and_save_config( - base_config: Dict, variation: Dict[str, any], output_path: pathlib.Path + base_config: Dict[str, Any], variation: Dict[str, Any], output_path: pathlib.Path ) -> None: """ Modify base configuration with variation parameters and save to new file. @@ -573,27 +573,27 @@ def main( init_logger() # Load base configuration - logging.info(f"Loading base configuration from {inifile}") + logging.info(f"Loading base configuration from {inifile}.") try: with open(inifile, "r", encoding="utf8") as f: base_config = json.load(f) except FileNotFoundError: - logging.error(f"Base configuration file not found: {inifile}") + logging.error(f"Base configuration file not found: {inifile}.") raise typer.Exit(code=1) # Load variations - logging.info(f"Loading variations from {variations_file}") + logging.info(f"Loading variations from {variations_file}.") try: variations = load_variations(variations_file) except (FileNotFoundError, json.JSONDecodeError, ValueError) as e: - logging.error(f"Error loading variations: {e}") - raise typer.Exit(code=1) + logging.error(f"Error loading variations: {e}.") + raise typer.Exit(code=2) # Create output directory output_dir.mkdir(parents=True, exist_ok=True) # Save a copy of the variations used for this run - timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") run_info = { "timestamp": timestamp, "base_config": str(inifile), @@ -631,10 +631,10 @@ def main( # Run simulation try: - evac_time = start_simulation(new_config_path, output_path) + evac_time = start_simulation(str(new_config_path), str(output_path)) status = "completed" except Exception as e: - logging.error(f"Error in simulation: {e}") + logging.error(f"Error in simulation: {e}.") evac_time = None status = "failed" @@ -650,18 +650,17 @@ def main( } results.append(result) - logging.info(f"Status: {status}") + logging.info(f"Status: {status}.") if evac_time is not None: - logging.info(f"Evacuation time: {evac_time:.2f} [s]") + logging.info(f"Evacuation time: {evac_time:.2f} [s].") # Save all results results_file = output_dir / f"results_{timestamp}.json" with open(results_file, "w") as f: json.dump(results, f, indent=4) - logging.info(f"\nSimulation batch completed. Results saved to {results_file}") + logging.info(f"\nSimulation batch completed. Results saved to {results_file}.") - # Print summary completed = sum(1 for r in results if r["status"] == "completed") failed = sum(1 for r in results if r["status"] == "failed") logging.info("\nSummary:")