SIwave log parser – pyedb.workflows.utilities.siwave_log_parser#
SIwave log file parser for extracting simulation results and metrics.
This module provides tools to parse Ansys SIwave batch simulation logs into structured dataclasses, making it easy to extract timing information, warnings, profile data, and simulation status.
Examples#
Basic usage for parsing a SIwave log file:
>>> from pyedb.workflows.utilities.siwave_log_parser import SiwaveLogParser
>>> parser = SiwaveLogParser(r"C:\path o\siwave.log")
>>> log = parser.parse()
>>> log.summary()
>>> log.to_json("siwave.json")
Check simulation completion status:
>>> if log.is_completed():
... print("Simulation completed successfully")
... else:
... print("Simulation failed or was aborted")
Overview#
The SIwave log parser extracts structured data from Ansys SIwave batch solve logs, including version information, batch execution metadata, simulation settings, warnings, profiling data, and completion status.
Key Features:
Automatic detection of simulation completion status (Normal Completion vs. Aborted)
Extraction of electrical short warnings with precise coordinates
Performance profiling data (timing, memory usage)
Support for multiple timestamp formats
JSON export capability
Quick start#
Basic usage:
from pyedb.workflows.utilities.siwave_log_parser import SiwaveLogParser
# Parse a SIwave log file
parser = SiwaveLogParser("path/to/siwave.log")
log = parser.parse()
# Check simulation status
if log.is_completed():
print(f"✓ Simulation completed successfully")
else:
print(f"✗ Simulation failed or was aborted")
# Display summary
log.summary()
# Export to JSON
log.to_json("results.json", indent=2)
Top-level façade#
- class pyedb.workflows.utilities.siwave_log_parser.SiwaveLogParser(log_path: str | Path)#
Bases:
objectHigh-level parser that orchestrates all block parsers.
This class provides the main interface for parsing SIwave log files. It coordinates multiple specialized parsers to extract version info, batch metadata, simulation settings, warnings, and profile data.
- Parameters:
- log_path
strorpathlib.Path Path to the SIwave log file to parse.
- log_path
Examples
Basic usage:
>>> from pyedb.workflows.utilities.siwave_log_parser import SiwaveLogParser >>> parser = SiwaveLogParser("/tmp/siwave.log") >>> log = parser.parse() >>> log.summary() Project : my_design Run by : engineer ...
Check for warnings:
>>> parser = SiwaveLogParser("simulation.log") >>> log = parser.parse() >>> if log.warnings: ... print(f"Found {len(log.warnings)} warnings") ... for w in log.warnings[:3]: ... print(f" {w.category}: {w.message}")
Export to JSON:
>>> parser = SiwaveLogParser("simulation.log") >>> log = parser.parse() >>> log.to_json("output.json", indent=2)
- parse() ParsedSiwaveLog#
Execute all sub-parsers and return a unified object.
- Returns:
ParsedSiwaveLogStructured representation of the entire log including version info, batch metadata, settings, warnings, and profile data.
Examples
Parse and check completion:
>>> parser = SiwaveLogParser("siwave.log") >>> log = parser.parse() >>> if log.is_completed(): ... print("Simulation completed successfully") ... else: ... print("Simulation did not complete")
Access profile data:
>>> parser = SiwaveLogParser("siwave.log") >>> log = parser.parse() >>> for entry in log.profile: ... print(f"{entry.task}: {entry.real_time}")
Aggregated result object#
- class pyedb.workflows.utilities.siwave_log_parser.ParsedSiwaveLog(aedt: ~pyedb.workflows.utilities.siwave_log_parser.AEDTVersion, batch: ~pyedb.workflows.utilities.siwave_log_parser.BatchInfo, settings: ~pyedb.workflows.utilities.siwave_log_parser.SimSettings, warnings: list[~pyedb.workflows.utilities.siwave_log_parser.WarningEntry] = <factory>, profile: list[~pyedb.workflows.utilities.siwave_log_parser.ProfileEntry] = <factory>)#
Bases:
objectRoot container returned by SiwaveLogParser.parse().
This class holds all parsed information from a SIwave log file and provides convenience methods for checking completion status, generating summaries, and exporting data.
- Attributes:
- aedt
AEDTVersion AEDT version information extracted from log header.
- batch
BatchInfo Batch run metadata including timestamps and user info.
- settings
SimSettings Simulation settings and configuration.
- warnings
listofWarningEntry Warning entries from the log. The default is an empty list.
- profile
listofProfileEntry Profile/timing entries showing task performance. The default is an empty list.
- aedt
Examples
>>> from datetime import datetime >>> from pathlib import Path >>> log = ParsedSiwaveLog( ... aedt=AEDTVersion(version="2025.1", build="123", location="C:\AEDT"), ... batch=BatchInfo( ... path="C:\project\test.siw", ... started=datetime(2025, 11, 10, 9, 0, 0), ... stopped=datetime(2025, 11, 10, 10, 0, 0), ... run_by="engineer", ... temp_dir="C:\temp", ... project_dir="C:\project", ... status="Normal Completion", ... ), ... settings=SimSettings( ... design_type="SIwave", ... allow_off_core=True, ... manual_settings=False, ... two_level=False, ... distribution_types=["Local"], ... machines=[], ... ), ... ) >>> log.is_completed() True
- is_aborted() bool#
Check if the simulation was aborted.
- Returns:
- bool
Trueif simulation did not complete normally,Falseotherwise.
Examples
>>> log = ParsedSiwaveLog( ... aedt=AEDTVersion("2025.1", "123", "C:\AEDT"), ... batch=BatchInfo( ... path="test.siw", ... started=datetime(2025, 1, 1), ... stopped=datetime(2025, 1, 1), ... run_by="user", ... temp_dir="", ... project_dir="", ... status="Aborted", ... ), ... settings=SimSettings("", False, False, False, [], []), ... ) >>> log.is_aborted() True
- is_completed() bool#
Check if the simulation completed normally.
- Returns:
- bool
Trueif status is'Normal Completion',Falseotherwise.
Examples
>>> log = ParsedSiwaveLog( ... aedt=AEDTVersion("2025.1", "123", "C:\AEDT"), ... batch=BatchInfo( ... path="test.siw", ... started=datetime(2025, 1, 1), ... stopped=datetime(2025, 1, 1), ... run_by="user", ... temp_dir="", ... project_dir="", ... status="Normal Completion", ... ), ... settings=SimSettings("", False, False, False, [], []), ... ) >>> log.is_completed() True
- summary() None#
Print a summary of the parsed log to stdout.
Examples
>>> log = ParsedSiwaveLog(aedt=..., batch=..., settings=...) >>> log.summary() Project : test_design Run by : engineer Started : Mon Nov 10 09:00:00 2025 Stopped : Mon Nov 10 10:00:00 2025 Status : Normal Completion Warnings: 0 Profile entries: 0
- to_dict() dict#
Deep-convert the entire object to JSON-serializable primitives.
- Returns:
dictPlain dict/list/scalar structure suitable for JSON serialization.
Examples
>>> log = ParsedSiwaveLog(aedt=..., batch=..., settings=...) >>> data_dict = log.to_dict() >>> isinstance(data_dict, dict) True >>> "aedt" in data_dict True
Data containers#
Version information#
- class pyedb.workflows.utilities.siwave_log_parser.AEDTVersion(version: str, build: str, location: str)#
Bases:
objectAEDT version information extracted from log header.
- Attributes:
Examples
>>> version = AEDTVersion(version="2025.1", build="12345", location="C:\Program Files\AnsysEM") >>> version.version '2025.1'
Batch execution metadata#
- class pyedb.workflows.utilities.siwave_log_parser.BatchInfo(path: str, started: datetime, stopped: datetime, run_by: str, temp_dir: str, project_dir: str, status: str = '')#
Bases:
objectBatch simulation run metadata.
- Attributes:
- path
str Full path to the project file.
- started
datetime Simulation start timestamp.
- stopped
datetime Simulation stop timestamp.
- run_by
str Username who executed the simulation.
- temp_dir
str Temporary directory used during simulation.
- project_dir
str Project working directory.
- status
str,optional Simulation completion status such as
'Normal Completion'or'Aborted'. The default is"".
- path
Examples
>>> from datetime import datetime >>> batch = BatchInfo( ... path="C:\project\design.siw", ... started=datetime(2025, 11, 10, 9, 0, 0), ... stopped=datetime(2025, 11, 10, 10, 30, 0), ... run_by="engineer", ... temp_dir="C:\temp", ... project_dir="C:\project", ... status="Normal Completion", ... ) >>> batch.status 'Normal Completion'
Simulation settings#
- class pyedb.workflows.utilities.siwave_log_parser.SimSettings(design_type: str, allow_off_core: bool, manual_settings: bool, two_level: bool, distribution_types: list[str], machines: list[str])#
Bases:
objectSimulation settings and configuration.
- Attributes:
- design_type
str Type of design being simulated.
- allow_off_corebool
Whether off-core solving is enabled.
- manual_settingsbool
Whether manual settings are being used.
- two_levelbool
Whether two-level solving is enabled.
- distribution_types
listofstr Distribution types configured for the simulation.
- machines
listofstr Machine specifications (RAM, cores, etc.).
- design_type
Examples
>>> settings = SimSettings( ... design_type="SIwave", ... allow_off_core=True, ... manual_settings=False, ... two_level=True, ... distribution_types=["Local"], ... machines=["localhost RAM: 32GB"], ... ) >>> settings.allow_off_core True
Warning entries#
- class pyedb.workflows.utilities.siwave_log_parser.WarningEntry(timestamp: datetime, category: str, net1: str, net2: str, layer: str, x: float, y: float, message: str)#
Bases:
objectSingle warning message from the simulation log.
- Attributes:
- timestamp
datetime When the warning occurred.
- category
str Warning category:
'SHORT'for electrical shorts or'OTHER'for other warnings.- net1
str First net involved (for SHORT warnings).
- net2
str Second net involved (for SHORT warnings).
- layer
str Layer name where the issue occurred.
- x
float X-coordinate in millimeters.
- y
float Y-coordinate in millimeters.
- message
str Complete warning message text.
- timestamp
Examples
>>> from datetime import datetime >>> warning = WarningEntry( ... timestamp=datetime(2025, 11, 10, 9, 15, 30), ... category="SHORT", ... net1="VCC", ... net2="GND", ... layer="TOP", ... x=12.5, ... y=34.8, ... message="Nets are electrically shorted", ... ) >>> warning.category 'SHORT'
Profile entries#
- class pyedb.workflows.utilities.siwave_log_parser.ProfileEntry(timestamp: ~datetime.datetime, task: str, real_time: str | None = None, cpu_time: str | None = None, memory: str | None = None, extra: dict[str, str] = <factory>)#
Bases:
objectPerformance profile entry showing task timing and resource usage.
- Attributes:
- timestamp
datetime When the task completed.
- task
str Task or operation name.
- real_time
str,optional Wall clock time in human-readable format. The default is
None.- cpu_time
str,optional CPU time consumed. The default is
None.- memory
str,optional Peak memory usage. The default is
None.- extra
dictofstrtostr,optional Additional metrics (e.g., number of elements). The default is an empty dict.
- timestamp
Examples
>>> from datetime import datetime >>> profile = ProfileEntry( ... timestamp=datetime(2025, 11, 10, 9, 30, 0), ... task="Mesh Generation", ... real_time="00:05:30", ... cpu_time="00:05:25", ... memory="2.5 GB", ... extra={"Number of elements": "50000"}, ... ) >>> profile.task 'Mesh Generation'
Block parsers (advanced usage)#
These parsers handle specific sections of the log file. Most users does not need
to use them directly, as they are orchestrated by SiwaveLogParser.
- class pyedb.workflows.utilities.siwave_log_parser.HeaderBlockParser(lines: list[str])#
Bases:
BlockParserExtract AEDT version information from the log header.
This parser searches through log lines to find version, build, and installation location information.
Examples
>>> lines = [ ... "ANSYS Electromagnetics Suite Version 2025.1 Build: 12345", ... "Location: C:\Program Files\AnsysEM\v251", ... ] >>> parser = HeaderBlockParser(lines) >>> version = parser.parse() >>> version.version '2025.1'
- parse() AEDTVersion#
Parse the stored lines and return an AEDTVersion instance.
- Returns:
AEDTVersionPopulated version data object containing version, build, and location.
Examples
>>> lines = ["Version 2025.1 Build: 12345", "Location: C:\AnsysEM"] >>> parser = HeaderBlockParser(lines) >>> info = parser.parse() >>> info.build '12345'
- class pyedb.workflows.utilities.siwave_log_parser.BatchSettingsBlockParser(lines: list[str])#
Bases:
BlockParserExtract batch information and simulation settings from the log.
This parser processes batch run metadata including timestamps, user info, directories, and simulation configuration settings.
Examples
>>> lines = [ ... "Batch Solve/Save: C:\project\design.siw", ... "Starting Batch Run: 11/10/2025 09:00:00 AM", ... "Running as user : engineer", ... "Design type: SIwave", ... "Allow off core: True", ... ] >>> parser = BatchSettingsBlockParser(lines) >>> batch, settings = parser.parse() >>> batch.run_by 'engineer' >>> settings.design_type 'SIwave'
- parse() tuple[BatchInfo, SimSettings]#
Parse batch information and simulation settings.
- Returns:
tuple[BatchInfo,SimSettings]Tuple containing batch run metadata and simulation settings.
Examples
>>> lines = ["Batch Solve/Save: test.siw", "Design type: SIwave"] >>> parser = BatchSettingsBlockParser(lines) >>> batch, settings = parser.parse() >>> isinstance(batch, BatchInfo) True >>> isinstance(settings, SimSettings) True
- class pyedb.workflows.utilities.siwave_log_parser.WarningsBlockParser(lines: list[str])#
Bases:
BlockParserExtract warning entries from the simulation log.
This parser identifies and extracts warning messages, particularly focusing on electrical short warnings with location information.
Examples
>>> lines = [ ... "11/10/2025 09:15:30 AM [warning] Geometry on nets VCC and GND on layer \"TOP\" " ... "are electrically shorted at approximately (12.5, 34.8)mm" ... ] >>> parser = WarningsBlockParser(lines) >>> warnings = parser.parse() >>> warnings[0].category 'SHORT' >>> warnings[0].net1 'VCC'
- parse() list[WarningEntry]#
Parse warning messages from log lines.
- Returns:
listofWarningEntryList of parsed warning entries with categorization and location data.
Examples
>>> lines = ["No warnings"] >>> parser = WarningsBlockParser(lines) >>> warnings = parser.parse() >>> len(warnings) 0
- class pyedb.workflows.utilities.siwave_log_parser.ProfileBlockParser(lines: list[str])#
Bases:
BlockParserExtract profile entries showing task timing and resource usage.
This parser processes [PROFILE] tagged lines to extract performance metrics including real time, CPU time, memory usage, and additional task-specific data.
Examples
>>> lines = [ ... "11/10/2025 09:30:00 AM [PROFILE] Mesh Generation : Real Time 00:05:30 : " ... "CPU Time 00:05:25 : Memory 2.5 GB : Number of elements: 50000" ... ] >>> parser = ProfileBlockParser(lines) >>> profiles = parser.parse() >>> profiles[0].task 'Mesh Generation' >>> profiles[0].real_time '00:05:30'
- parse() list[ProfileEntry]#
Parse profile entries showing task timing and resource usage.
- Returns:
listofProfileEntryList of profile entries with timing and resource consumption data.
Examples
>>> lines = ["Regular log line without profile"] >>> parser = ProfileBlockParser(lines) >>> profiles = parser.parse() >>> len(profiles) 0
Base class#
Utility helpers#
The functions below are private by convention (leading underscore) but are exposed in the documentation for contributors and advanced users.
- pyedb.workflows.utilities.siwave_log_parser._parse_ts(txt: str) datetime#
Convert timestamp strings to datetime objects.
Parse timestamp strings in two different SIwave log formats and return a datetime object. Supports both date-first and time-first formats.
- Parameters:
- txt
str Timestamp string from SIwave log. Supports two formats:
Date-first:
'11/10/2025 05:46:09 PM'Time-first:
'11:55:29 AM Oct 12, 2025'
- txt
- Returns:
datetimeParsed datetime object.
Examples
>>> _parse_ts("11/10/2025 05:46:09 PM") datetime.datetime(2025, 11, 10, 17, 46, 9) >>> _parse_ts("11:55:29 AM Oct 12, 2025") datetime.datetime(2025, 10, 12, 11, 55, 29) >>> try: ... _parse_ts("invalid timestamp") ... except ValueError as e: ... print("Cannot parse") Cannot parse
- pyedb.workflows.utilities.siwave_log_parser._split_kv(line: str, sep: str = ':') tuple[str, str]#
Split a key-value line into key and value strings.
Parse lines in the format
'key: value'and return a tuple of the stripped key and value parts.- Parameters:
- Returns:
Examples
>>> _split_kv("Real Time: 00:05:30") ('Real Time', '00:05:30') >>> _split_kv("Number of cores=4", sep="=") ('Number of cores', '4') >>> _split_kv("Status: Normal Completion") ('Status', 'Normal Completion')
- pyedb.workflows.utilities.siwave_log_parser._as_dict(obj: Any) Any#
Recursively convert dataclasses to JSON-serializable primitives.
Convert dataclass instances, lists, and Path objects to plain Python types that can be serialized to JSON.
- Parameters:
- obj
Any Object to convert. Can be a dataclass, list, Path, or primitive type.
- obj
- Returns:
AnyPlain Python representation. Dataclasses become dicts, Paths become strings, lists are recursively processed, and primitives pass through.
Examples
>>> from dataclasses import dataclass >>> from pathlib import Path >>> @dataclass ... class Sample: ... name: str ... value: int >>> _as_dict(Sample("test", 42)) {'name': 'test', 'value': 42} >>> _as_dict(Path("/tmp/file.txt")) '/tmp/file.txt' >>> _as_dict([1, 2, Path("/test"), "hello"]) [1, 2, '/test', 'hello']
Examples#
Check simulation completion status#
from pyedb.workflows.utilities.siwave_log_parser import SiwaveLogParser
parser = SiwaveLogParser("siwave.log")
log = parser.parse()
if log.is_completed():
print("Status:", log.batch.status)
print("Runtime:", log.batch.stopped - log.batch.started)
else:
print("Simulation was aborted or failed")
Extract warnings#
parser = SiwaveLogParser("siwave.log")
log = parser.parse()
# Get all electrical short warnings
shorts = [w for w in log.warnings if w.category == "SHORT"]
for warning in shorts:
print(f"Short between {warning.net1} and {warning.net2}")
print(f" Layer: {warning.layer}")
print(f" Location: ({warning.x:.3f}, {warning.y:.3f}) mm")
Analyze performance#
parser = SiwaveLogParser("siwave.log")
log = parser.parse()
# Display profiling information
for entry in log.profile:
print(f"Task: {entry.task}")
print(f" Real Time: {entry.real_time}")
print(f" CPU Time: {entry.cpu_time}")
print(f" Memory: {entry.memory}")
Batch processing#
from pathlib import Path
from pyedb.workflows.utilities.siwave_log_parser import SiwaveLogParser
# Process multiple log files
log_dir = Path("simulation_results")
completed = []
failed = []
for log_file in log_dir.glob("**/*.log"):
try:
parser = SiwaveLogParser(log_file)
log = parser.parse()
if log.is_completed():
completed.append(
{
"project": log.batch.path,
"warnings": len(log.warnings),
"runtime": (log.batch.stopped - log.batch.started).total_seconds(),
}
)
else:
failed.append({"project": log.batch.path, "status": log.batch.status})
except Exception as e:
print(f"Failed to parse {log_file}: {e}")
print(f"Completed: {len(completed)}, Failed: {len(failed)}")
Export to JSON#
parser = SiwaveLogParser("siwave.log")
log = parser.parse()
# Export with pretty formatting
log.to_json("results.json", indent=2)
# Convert to dictionary for further processing
data = log.to_dict()
See also#
HFSS log parser – pyedb.workflows.utilities.hfss_log_parser - HFSS log parser with similar functionality
workflows_api - Workflow utilities overview