## Removed Duplicate Directories - Deleted old `dashboard/` (replaced by atomizer-dashboard) - Deleted old `mcp_server/` Python tools (moved model_discovery to optimization_engine) - Deleted `tests/mcp_server/` (obsolete tests) - Deleted `launch_dashboard.bat` (old launcher) ## Consolidated Code - Moved `mcp_server/tools/model_discovery.py` to `optimization_engine/model_discovery/` - Updated import in `optimization_config_builder.py` - Deleted stub `extract_mass.py` (use extract_mass_from_bdf instead) - Deleted unused `intelligent_setup.py` and `hybrid_study_creator.py` - Archived `result_extractors/` to `archive/deprecated/` ## Documentation Cleanup - Deleted deprecated `docs/06_PROTOCOLS_DETAILED/` (14 files) - Archived dated dev docs to `docs/08_ARCHIVE/sessions/` - Archived old plans to `docs/08_ARCHIVE/plans/` - Updated `docs/protocols/README.md` with SYS_15 ## Skills Consolidation - Archived redundant study creation skills to `.claude/skills/archive/` - Kept `core/study-creation-core.md` as canonical ## Housekeeping - Updated `.gitignore` to prevent `nul` and `_dat_run*.dat` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
"""
|
|
Pluggable Result Extractor System
|
|
|
|
Base classes and implementations for extracting metrics from FEA results.
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Dict, Any, Optional
|
|
from pathlib import Path
|
|
|
|
|
|
class ResultExtractor(ABC):
|
|
"""Base class for all result extractors."""
|
|
|
|
@abstractmethod
|
|
def extract(self, result_files: Dict[str, Path], config: Dict[str, Any]) -> Dict[str, float]:
|
|
"""
|
|
Extract metrics from FEA results.
|
|
|
|
Args:
|
|
result_files: Dictionary mapping file types to paths (e.g., {'op2': Path(...), 'f06': Path(...)})
|
|
config: Extractor-specific configuration parameters
|
|
|
|
Returns:
|
|
Dictionary mapping metric names to values
|
|
"""
|
|
pass
|
|
|
|
@property
|
|
@abstractmethod
|
|
def required_files(self) -> list[str]:
|
|
"""List of required file types (e.g., ['op2'], ['f06'], etc.)."""
|
|
pass
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""Extractor name for registration."""
|
|
return self.__class__.__name__.replace("Extractor", "").lower()
|
|
|
|
|
|
# Registry of available extractors
|
|
_EXTRACTOR_REGISTRY: Dict[str, type[ResultExtractor]] = {}
|
|
|
|
|
|
def register_extractor(extractor_class: type[ResultExtractor]) -> type[ResultExtractor]:
|
|
"""Decorator to register an extractor."""
|
|
_EXTRACTOR_REGISTRY[extractor_class().name] = extractor_class
|
|
return extractor_class
|
|
|
|
|
|
def get_extractor(name: str) -> Optional[type[ResultExtractor]]:
|
|
"""Get extractor class by name."""
|
|
return _EXTRACTOR_REGISTRY.get(name)
|
|
|
|
|
|
def list_extractors() -> list[str]:
|
|
"""List all registered extractor names."""
|
|
return list(_EXTRACTOR_REGISTRY.keys())
|
|
|
|
|
|
__all__ = [
|
|
"ResultExtractor",
|
|
"register_extractor",
|
|
"get_extractor",
|
|
"list_extractors",
|
|
]
|