Bug 1 — Journal (solve_simulation.py simple workflow): Expression lookup for p173 fails silently for derived/measurement expressions, so _temp_mass.txt was never written. Added MeasureManager fallback via extract_part_mass() (already used in assembly workflow). Bug 2 — Extractor (extract_mass_from_expression.py): Journal writes 'p173=<value>' format but extractor tried float() on the whole content including 'p173='. Added key=value parsing. Defense in depth — nx_interface.py: Added stdout parsing fallback: if _temp_mass.txt still missing, parse mass from journal output captured via solver.py stdout passthrough. Files changed: - optimization_engine/nx/solve_simulation.py — MeasureManager fallback - optimization_engine/extractors/extract_mass_from_expression.py — key=value parse - optimization_engine/nx/solver.py — include stdout in result dict - projects/hydrotech-beam/studies/01_doe_landscape/nx_interface.py — stdout fallback Tags: hydrotech-beam, mass-extraction
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
"""
|
|
Extract mass from NX measure expression
|
|
|
|
This extractor reads mass from a temp file written by solve_simulation.py journal.
|
|
The journal extracts the mass from expression p173 and writes it to _temp_mass.txt
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from typing import Dict, Any
|
|
import sys
|
|
|
|
|
|
def extract_mass_from_expression(prt_file: Path, expression_name: str = "p173") -> float:
|
|
"""
|
|
Extract mass from NX expression by reading temp file.
|
|
|
|
The solve_simulation.py journal extracts the p173 expression value
|
|
and writes it to _temp_mass.txt in the model directory.
|
|
|
|
Args:
|
|
prt_file: Path to .prt file with mass expression
|
|
expression_name: Name of the expression containing mass (default: "p173")
|
|
|
|
Returns:
|
|
Mass in kilograms
|
|
"""
|
|
prt_file = Path(prt_file)
|
|
|
|
if not prt_file.exists():
|
|
raise FileNotFoundError(f"Part file not found: {prt_file}")
|
|
|
|
# The mass is written to _temp_mass.txt in the same directory as the .prt
|
|
model_dir = prt_file.parent
|
|
mass_file = model_dir / "_temp_mass.txt"
|
|
|
|
if not mass_file.exists():
|
|
raise FileNotFoundError(
|
|
f"Mass temp file not found: {mass_file}\n"
|
|
f"The solve_simulation.py journal should have created this file."
|
|
)
|
|
|
|
# Read mass from file
|
|
try:
|
|
with open(mass_file, 'r') as f:
|
|
content = f.read().strip()
|
|
|
|
# Handle key=value format (e.g., "p173=1185.767")
|
|
if '=' in content:
|
|
content = content.split('=', 1)[1]
|
|
|
|
mass_kg = float(content)
|
|
|
|
print(f"[OK] Mass from {expression_name}: {mass_kg:.6f} kg ({mass_kg * 1000:.2f} g)")
|
|
return mass_kg
|
|
|
|
except ValueError as e:
|
|
raise ValueError(f"Could not parse mass from {mass_file} (content: {content!r}): {e}")
|
|
except Exception as e:
|
|
raise RuntimeError(f"Failed to read mass file: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > 1:
|
|
prt_file = Path(sys.argv[1])
|
|
expression_name = sys.argv[2] if len(sys.argv) > 2 else "p173"
|
|
else:
|
|
print(f"Usage: python {sys.argv[0]} <prt_file> [expression_name]")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
mass_kg = extract_mass_from_expression(prt_file, expression_name)
|
|
print(f"\nMass: {mass_kg:.6f} kg ({mass_kg * 1000:.2f} g)")
|
|
except Exception as e:
|
|
print(f"\nERROR: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|