dpeva.labeling.strategy 源代码

"""
Resubmission Strategy
=====================

Handles the strategy for resubmitting failed calculations by modifying input parameters.
"""

import logging
from typing import Dict, List, Any
from pathlib import Path

logger = logging.getLogger(__name__)

[文档] class ResubmissionStrategy: """ Manages parameters for each calculation attempt. This class handles the retrieval and application of parameters for different attempts in the calculation workflow. It allows for modifying input files based on the attempt index. """ def __init__(self, attempt_params: List[Dict[str, Any]] = None): """ Initialize with a list of parameter sets for each attempt. Args: attempt_params: List of dicts, where index i contains params for attempt i. Example: [ {"mixing_beta": 0.4}, # Attempt 0 (Initial) {"mixing_beta": 0.1}, # Attempt 1 (Retry 1) ] """ self.attempt_params = attempt_params or []
[文档] def get_params(self, attempt: int) -> Dict[str, Any]: """Get parameters for a specific attempt index.""" if attempt < 0 or attempt >= len(self.attempt_params): return None return self.attempt_params[attempt]
[文档] def apply(self, task_dir: str, attempt: int) -> bool: """ Apply the parameters for the given attempt to the INPUT file. Args: task_dir: Directory containing the INPUT file. attempt: The attempt index (0-based). Returns: True if applied successfully, False if no params for this attempt. """ params = self.get_params(attempt) if params is None: logger.warning(f"No parameters defined for attempt {attempt}") return False input_file = Path(task_dir) / "INPUT" if not input_file.exists(): logger.error(f"INPUT file not found: {input_file}") return False return self._modify_input_file(input_file, params)
def _modify_input_file(self, filepath: Path, changes: Dict[str, Any]) -> bool: """ Modify specific keys in the INPUT file. """ try: with open(filepath, 'r') as f: lines = f.readlines() except Exception as e: logger.error(f"Error reading {filepath}: {e}") return False new_lines = [] modified_keys = set() for line in lines: stripped = line.strip() # Skip empty or comments if not stripped or stripped.startswith('#') or stripped.startswith('INPUT_PARAMETERS'): new_lines.append(line) continue parts = stripped.split() if len(parts) >= 2: key = parts[0] if key in changes: # Replace value # Try to preserve formatting (indentation) original_key_end = line.find(key) + len(key) # Find value start value_start = -1 for i in range(original_key_end, len(line)): if not line[i].isspace(): value_start = i break if value_start != -1: prefix = line[:value_start] new_line = f"{prefix}{changes[key]}\n" else: new_line = f"{key:<20} {changes[key]}\n" new_lines.append(new_line) modified_keys.add(key) logger.debug(f"Modified {key} -> {changes[key]}") else: new_lines.append(line) else: new_lines.append(line) # Add missing keys for key, value in changes.items(): if key not in modified_keys: new_lines.append(f"{key:<20} {value}\n") logger.debug(f"Added {key} -> {value}") try: with open(filepath, 'w') as f: f.writelines(new_lines) return True except Exception as e: logger.error(f"Error writing {filepath}: {e}") return False