femic.patchworks_runtime Module
The femic.patchworks_runtime module is FEMIC’s Patchworks launch and
runtime-preparation seam. It takes an already exported Patchworks package and
handles the operational work needed to run Matrix Builder or related helper
commands: load runtime config, validate host prerequisites, choose the correct
launcher mode, capture logs/manifests, and prepare the 1:1 stand/block dataset
used by the model runtime.
If you are debugging why Patchworks preflight fails, why Matrix Builder will
not launch on Windows or under Wine, or why the runtime package produced the
wrong tracks/blocks side effects, this is the first module to read. In
practice it owns:
Patchworks runtime config loading and validation
host-mode detection for native Windows versus Wine/Linux execution
preflight checks for Java, Wine, licensing, and exported input artifacts
command construction, launch, and manifest/log capture
block/topology preparation from exported fragments shapefiles
Start Here If…
Use this page first if you are trying to:
understand the boundary between Patchworks export synthesis and actual runtime execution
debug patchworks preflight, patchworks matrix-build, or patchworks build-blocks
inspect why FEMIC chose native Windows Java versus Wine launch mode
trace where stdout/stderr/manifests are written for runtime launches
understand what runtime config fields are required before Matrix Builder can run
Typical maintenance path:
Start with
load_patchworks_runtime_config()if the issue begins with a runtime YAML/JSON config file.Move to
run_patchworks_preflight()if the problem is about missing Java, Wine, patchworks.jar, license values, or runtime inputs.Read
run_patchworks_command()orrun_patchworks_beanshell_script()if the failure happens during command launch or manifest capture.Read
build_patchworks_blocks_dataset()if the problem is inblocks.shp/ topology generation rather than Matrix Builder launch.
Typical Usage
The common operator-facing path is:
femic patchworks preflight --instance-root external/femic-k3z-instance --config config/patchworks.runtime.windows.yaml
femic patchworks build-blocks --instance-root external/femic-k3z-instance --config config/patchworks.runtime.windows.yaml
femic patchworks matrix-build --instance-root external/femic-k3z-instance --config config/patchworks.runtime.windows.yaml --run-id k3z_docs_example
At the Python level, maintainers usually call preflight before launch:
from pathlib import Path
from femic.patchworks_runtime import load_patchworks_runtime_config, run_patchworks_preflight
config = load_patchworks_runtime_config(Path("config/patchworks.runtime.windows.yaml"))
result = run_patchworks_preflight(config)
On native Windows, FEMIC can also supervise noninteractive Matrix Builder runs
and close the spawned Matrix Builder GUI window automatically once fresh output
activity has stabilized. On hosts like the current FEMIC dev environment, the
same supervised cleanup also tears down the matching Patchworks launcher
cmd.exe shell tree when it lingers after the Java process is done. This
behavior is controlled through the runtime config surface:
matrix_builder.auto_close_window_on_successmatrix_builder.auto_close_settle_secondsmatrix_builder.auto_close_timeout_seconds
This automation is intended for the local rebuild workflow and does not replace manifest/log review when something looks wrong.
Critical Headless Scheduling Insight
The current proving-ground no-GUI Patchworks seam has one especially important runtime rule:
in the headless BeanShell path, let
ca.spatial.patchworks.Control.waitForIterations()own scheduler startupdo not call
control.resume()immediately before that wait
Live proving-ground smokes showed that the explicit pre-resume() path was
the source of the earlier java.lang.IllegalStateException: Not suspended
failure. Once that call was removed, the K3Z proving-ground helper could:
reach
PatchWorks_Initcompletion,wait one unattended iteration,
suspend after the wait,
call
saveStage(...), andreturn control with a success manifest and saved stage directory.
FEMIC now supervises these Windows headless runs directly:
success and failure are detected from explicit trace/log markers
failed runs are killed automatically instead of leaving dead shells behind
successful runs are also torn down automatically after the success marker and saved-stage verification
First Real Headless Scenario Smoke
The proving-ground seam is now beyond a passive saveStage(...) proof.
FEMIC supports a minimal headless scenario mode,
max-even-flow-smoke, that activates one target before the bounded wait/save
cycle. The first fully useful proving-ground smoke on
analysis/intensive_light_standstructure.pin showed that:
product.Yield.managed.Totalcan be activated headlessly with a modest annual minimum,the saved
scenario/targetStatus.csvrecords that target as active,the saved
scenario/targetSummary.csvcontains non-zero managed-yield currents and derivedflow.even.product.Yield.managed.Totalvalues, andthe saved
scenario/schedule.csvis non-empty and contains real managed treatments.
One important nuance from the proving-ground evidence:
directly activating
flow.even.product.Yield.managed.Totalchanged target state and objective values but still left the saved schedule empty;activating the underlying
product.Yield.managed.Totaltarget produced the first useful no-GUI scheduling smoke.
How This Fits Into The Pipeline
This module sits after femic.fmg.patchworks. The export layer writes the
package content. This runtime layer decides whether that package is runnable on
the current host and then launches the proprietary runtime tools.
At a high level, the owning sequence is:
load and validate runtime config
verify host/runtime prerequisites with preflight
build and launch the correct command for the current host mode
capture stdout/stderr/manifests and detect fatal runtime signatures
optionally prepare
blocks.shpand topology CSV inputs expected by the model runtime
That means this module is the operational boundary, not the content-synthesis
boundary. If forestmodel.xml or fragments semantics are already wrong, the
bug usually belongs in femic.fmg.patchworks. If the package is correct
but runtime tooling still fails, this module is the likely owner.
Key Entry Surfaces
The highest-value entrypoints in this module are:
load_patchworks_runtime_config()Load and validate the Patchworks runtime config file.run_patchworks_preflight()Verify that the host, license, Java/Wine, and input artifacts are ready.run_patchworks_command()Launch Matrix Builder or the app chooser and capture logs/manifests.run_patchworks_beanshell_script()Launch Beanshell-based helper scripts through the same runtime shell.build_patchworks_blocks_dataset()Prepareblocks.shpand optional topology CSV from the fragments dataset.build_matrix_builder_command_string()build_appchooser_command_string()build_beanshell_command_string()Build the command text that the runtime layer will execute.
The main runtime payload classes are also useful because they define the core contracts explicitly:
PatchworksRuntimeConfigPatchworksPreflightResultPatchworksExecutionResultPatchworksBlocksBuildResultPatchworksConfigError
Runtime Contract Surfaces
The most important runtime contracts in this module are:
runtime config must contain valid patchworks and matrix_builder sections
the runtime must have a usable Java surface on Windows or a usable Wine + Java surface on non-Windows hosts
on known-good Windows workstations, licensing should usually resolve through the existing system-level SPS_LICENSE_SERVER environment value
patchworks.license_value is a fallback override seam and should not replace a valid system license setting unless that override is intentional
SPSHOME must point to the Patchworks install root visible to the chosen launcher mode
Matrix Builder requires a valid fragments dataset, output tracks directory, and ForestModel XML path before launch
runtime launches must emit logs/manifests even when the proprietary tool exits badly
This is the code-level owner of the runtime behavior documented in:
Host Modes And Launch Paths
One of the most important behaviors in this module is the host split:
on native Windows, FEMIC launches Java directly
on non-Windows hosts, FEMIC prefers Wine (wine64 or wine)
when patchworks.use_xvfb is enabled, non-Windows launches can be wrapped in xvfb-run -a
That host-mode split affects:
which executable FEMIC searches for
how paths are converted into Windows-visible arguments
where SPSHOME and license values must be visible
which failure signatures are expected during preflight versus runtime launch
If a command works on one host family but not the other, this module is where the behavior diverges intentionally.
Artifacts And Failure Seams
The most important runtime artifacts this module produces are:
patchworks_matrixbuilder_stdout-<run_id>.log
patchworks_matrixbuilder_stderr-<run_id>.log
patchworks_matrixbuilder_manifest-<run_id>.json
patchworks_beanshell_* logs/manifests for Beanshell runs
blocks/blocks.shp and optional topology_blocks_*r.csv
The common failure boundaries in this module are:
invalid runtime config missing required sections or malformed fields fail fast here
missing launcher/runtime prerequisites Java, Wine, patchworks.jar, SPSHOME, or license wiring may be absent even when the exported package itself is valid
fatal runtime stderr signatures Matrix Builder can “run” but still report fatal conditions only through stderr patterns that this module scans for explicitly
output-not-ready conditions a zero/empty tracks output directory after launch is treated as a runtime failure even if the JVM exit code is not obviously fatal
block/topology preparation problems missing fragments geometry, no usable stand/block id field, or backend misuse can break the build-blocks path before Matrix Builder ever runs
Headless Proving Ground
The native-Windows no-GUI proving-ground seam is now real in this module.
Current documented runtime rules:
let
Control.waitForIterations(...)own scheduler startup in the BeanShell helper;do not pre-issue
control.resume()in the headless path or Patchworks can fail withjava.lang.IllegalStateException: Not suspended;FEMIC supervises the run by watching explicit headless trace/log markers and self-terminates the Patchworks Java tree on both success and failure.
The first useful headless scheduling proof used a tiny scenario mode,
max-even-flow-smoke, on the K3Z proving-ground surface. The current best
proof point is run p49_smoke_20260328q:
phase 1 seeds
product.Yield.managed.Totalwith a modest annual minimum;phase 2 suspends, activates
flow.even.product.Yield.managed.Total, and runs a second bounded wait;the saved stage records both targets as active in
targetStatus.csv;targetSummary.csvshows non-zero currents for both targets; andschedule.csvremains non-empty (677 lines) with real managed treatments.
The normal CLI/default-target path is also now proven:
proving-ground smoke
p49_smoke_20260328romitted an explicit scenario target and relied on FEMIC’s defaultproduct.Yield.managed.Totalresolution;both the underlying target and the
flow.even.*companion still ended up active intargetStatus.csv; andschedule.csvremained non-empty (788 lines).
The current closeout-level proving ground is now the real base K3Z surface:
max-even-flow-smokedefaults to a useful K3Z recipe when the caller leaves--iterationsat the placeholder value: target defaults toproduct.Yield.managed.Totaland iterations default to100000.the BeanShell helper now seeds the underlying harvest target first and configures that base target with
LINEAR=true, maximum =200000in all periods at default weight, and minimum =10000per period.after the seed phase, the helper activates
flow.even.product.Yield.managed.Totalwith minimum = maximum =0and minimum weight = maximum weight =100across all periods.proving-ground smoke
p49_base_closeout_20260328bran againstanalysis/base.pinand saved a stage where both the underlying target and the even-flow companion were active,targetStatus.csvshowed the base target withLINEAR=true, the base target summary stabilized around122200per period inside the100000..200000band, the even-flow target summary stayed tightly clustered near zero, andschedule.csvremained non-empty (480 lines).
That means this module now owns a real unattended Patchworks launch/analyze/ save/exit seam instead of a launch-only experiment.
Cross-References
Guides and references that pair especially closely with this module:
Related API pages:
Patchworks runtime helpers for Patchworks Matrix Builder execution.
- class femic.patchworks_runtime.PatchworksBlocksBuildResult(model_dir, fragments_shapefile_path, blocks_shapefile_path, topology_csv_path, block_count, stand_id_field, topology_edge_count, topology_radius_m)[source]
Bases:
objectOutputs from preparing a 1:1 stand:block blocks dataset.
- Parameters:
model_dir (Path)
fragments_shapefile_path (Path)
blocks_shapefile_path (Path)
topology_csv_path (Path | None)
block_count (int)
stand_id_field (str)
topology_edge_count (int)
topology_radius_m (float)
- block_count: int
- blocks_shapefile_path: Path
- fragments_shapefile_path: Path
- model_dir: Path
- stand_id_field: str
- topology_csv_path: Path | None
- topology_edge_count: int
- topology_radius_m: float
- exception femic.patchworks_runtime.PatchworksConfigError[source]
Bases:
ValueErrorInvalid Patchworks runtime config.
- class femic.patchworks_runtime.PatchworksExecutionResult(run_id, command, command_string, returncode, stdout_log_path, stderr_log_path, manifest_path, failures, warnings=())[source]
Bases:
objectExecution outputs for a Patchworks command launch.
- Parameters:
run_id (str)
command (tuple[str, ...])
command_string (str)
returncode (int)
stdout_log_path (Path)
stderr_log_path (Path)
manifest_path (Path)
failures (tuple[str, ...])
warnings (tuple[str, ...])
- command: tuple[str, ...]
- command_string: str
- failures: tuple[str, ...]
- manifest_path: Path
- returncode: int
- run_id: str
- stderr_log_path: Path
- stdout_log_path: Path
- warnings: tuple[str, ...] = ()
- class femic.patchworks_runtime.PatchworksHeadlessRunResult(run_id, pin_path, stage_label, stage_dir, iterations, improvement, scenario_mode, scenario_target, scenario_min_annual, launcher_script_path, trace_log_path, execution, saved_file_count, failures)[source]
Bases:
objectExecution outputs for an unattended Patchworks PIN run.
- Parameters:
run_id (str)
pin_path (Path)
stage_label (str)
stage_dir (Path)
iterations (int)
improvement (float)
scenario_mode (str)
scenario_target (str | None)
scenario_min_annual (float | None)
launcher_script_path (Path)
trace_log_path (Path)
execution (PatchworksExecutionResult)
saved_file_count (int)
failures (tuple[str, ...])
- execution: PatchworksExecutionResult
- failures: tuple[str, ...]
- improvement: float
- iterations: int
- launcher_script_path: Path
- property manifest_path: Path
Return the headless-run manifest path.
- pin_path: Path
- property returncode: int
Return the effective run status code.
- run_id: str
- saved_file_count: int
- scenario_min_annual: float | None
- scenario_mode: str
- scenario_target: str | None
- stage_dir: Path
- stage_label: str
- trace_log_path: Path
- class femic.patchworks_runtime.PatchworksPreflightResult(config, launcher_executable, host_mode, license_host, errors, warnings)[source]
Bases:
objectPreflight report for Patchworks runtime execution.
- Parameters:
config (PatchworksRuntimeConfig)
launcher_executable (str | None)
host_mode (str)
license_host (str | None)
errors (tuple[str, ...])
warnings (tuple[str, ...])
- config: PatchworksRuntimeConfig
- errors: tuple[str, ...]
- host_mode: str
- launcher_executable: str | None
- license_host: str | None
- property ok: bool
Return True when preflight checks reported no errors.
- warnings: tuple[str, ...]
- class femic.patchworks_runtime.PatchworksRuntimeConfig(config_path, jar_path, wine_prefix, license_env, license_value, spshome, use_xvfb, fragments_path, matrix_output_dir, forestmodel_xml_path, accounts_exclude_regex, harvested_volume_utilization_by_treatment, auto_close_window_on_success, auto_close_settle_seconds, auto_close_timeout_seconds)[source]
Bases:
objectResolved runtime settings for Patchworks execution.
- Parameters:
config_path (Path)
jar_path (Path)
wine_prefix (Path | None)
license_env (str)
license_value (str)
spshome (str)
use_xvfb (bool)
fragments_path (Path)
matrix_output_dir (Path)
forestmodel_xml_path (Path)
accounts_exclude_regex (tuple[str, ...])
harvested_volume_utilization_by_treatment (dict[str, float])
auto_close_window_on_success (bool)
auto_close_settle_seconds (float)
auto_close_timeout_seconds (float)
- accounts_exclude_regex: tuple[str, ...]
- auto_close_settle_seconds: float
- auto_close_timeout_seconds: float
- auto_close_window_on_success: bool
- config_path: Path
- forestmodel_xml_path: Path
- fragments_path: Path
- harvested_volume_utilization_by_treatment: dict[str, float]
- jar_path: Path
- license_env: str
- license_value: str
- matrix_output_dir: Path
- spshome: str
- use_xvfb: bool
- wine_prefix: Path | None
- femic.patchworks_runtime.build_appchooser_command_string(config)[source]
Build Windows CMD command to open Patchworks app chooser.
- Parameters:
config (PatchworksRuntimeConfig)
- Return type:
str
- femic.patchworks_runtime.build_beanshell_command_string(*, config, script_path, script_args=())[source]
Build Windows CMD command to run a BeanShell script via IProperties.
- Parameters:
config (PatchworksRuntimeConfig)
script_path (Path)
script_args (tuple[str, ...])
- Return type:
str
- femic.patchworks_runtime.build_matrix_builder_command_string(config)[source]
Build the Windows CMD command to run Matrix Builder.
- Parameters:
config (PatchworksRuntimeConfig)
- Return type:
str
- femic.patchworks_runtime.build_patchworks_blocks_dataset(*, config, model_dir=None, fragments_shapefile_path=None, topology_radius_m=200.0, build_topology=True, topology_backend='python')[source]
Build 1:1 stand:block blocks.shp (and optional topology CSV).
- Parameters:
config (PatchworksRuntimeConfig)
model_dir (Path | None)
fragments_shapefile_path (Path | None)
topology_radius_m (float)
build_topology (bool)
topology_backend (Literal['python', 'patchworks-raster'])
- Return type:
PatchworksBlocksBuildResult
- femic.patchworks_runtime.find_wine_executable()[source]
Return preferred Wine executable path/name on PATH.
- Return type:
str | None
- femic.patchworks_runtime.format_command_for_display(command)[source]
Return shell-quoted command for human-readable logs.
- Parameters:
command (tuple[str, ...])
- Return type:
str
- femic.patchworks_runtime.infer_patchworks_model_dir(config)[source]
Infer Patchworks model root from runtime input/output paths.
- Parameters:
config (PatchworksRuntimeConfig)
- Return type:
Path
- femic.patchworks_runtime.is_windows_host()[source]
Return true when running on native Windows.
- Return type:
bool
- femic.patchworks_runtime.load_patchworks_runtime_config(path)[source]
Load and validate Patchworks runtime YAML/JSON config.
- Parameters:
path (Path)
- Return type:
PatchworksRuntimeConfig
- femic.patchworks_runtime.parse_license_server(value)[source]
Parse user@server license format.
- Parameters:
value (str)
- Return type:
tuple[str, str]
- femic.patchworks_runtime.run_patchworks_beanshell_script(*, config, script_path, script_args, log_dir, run_id=None)[source]
Execute a Patchworks BeanShell script via IProperties.
- Parameters:
config (PatchworksRuntimeConfig)
script_path (Path)
script_args (tuple[str, ...])
log_dir (Path)
run_id (str | None)
- Return type:
PatchworksExecutionResult
- femic.patchworks_runtime.run_patchworks_command(*, config, interactive, log_dir, run_id=None)[source]
Execute Patchworks command and capture logs+manifest.
- Parameters:
config (PatchworksRuntimeConfig)
interactive (bool)
log_dir (Path)
run_id (str | None)
- Return type:
PatchworksExecutionResult
- femic.patchworks_runtime.run_patchworks_headless_pin(*, config, pin_path, log_dir, run_id=None, stage_label=None, iterations=1, improvement=0.0, scenario_mode='none', scenario_target=None, scenario_min_annual=None)[source]
Run a Patchworks PIN unattended via the documented Patchworks seams.
- Parameters:
config (PatchworksRuntimeConfig)
pin_path (Path)
log_dir (Path)
run_id (str | None)
stage_label (str | None)
iterations (int)
improvement (float)
scenario_mode (str)
scenario_target (str | None)
scenario_min_annual (float | None)
- Return type:
PatchworksHeadlessRunResult
- femic.patchworks_runtime.run_patchworks_preflight(*, config, require_matrix_inputs=True)[source]
Run preflight checks before Patchworks execution.
- Parameters:
config (PatchworksRuntimeConfig)
require_matrix_inputs (bool)
- Return type:
PatchworksPreflightResult
- femic.patchworks_runtime.shutil_which(name)[source]
Wrapper for monkeypatch-friendly which lookup.
- Parameters:
name (str)
- Return type:
str | None
- femic.patchworks_runtime.to_wine_windows_path(path)[source]
Map absolute path to a Windows-style path for command arguments.
- Parameters:
path (Path)
- Return type:
str