Run at a beamline#
Goal: run many refinements unattended on a beamline workstation, often one shared by several users. Keep GSAS-II loaded between runs, run batches of recipes, and find out what failed without watching every run.
You need:
The environment of your engine (Install).
Recipes that validate, with the instrument calibrated (Calibrate the instrument).
1. Check the environment#
pixi run -e gsasii powderline --doctor
The report lists the PowderLine version, the gateways it finds, each
engine’s installed version against the version PowderLine supports, and the
GSAS-II server’s state. In the core-only environment
(pixi run powderline --doctor) it looks like this:
PowderLine 0.2.0 (Python 3.13.15, Linux-…)
python: …/.pixi/envs/default/bin/python
gateways (3, from the powderline.gateways entry points):
easydiffraction workflows easydiffraction.rietveld requires ==0.21.1
engine: not installed in this environment
gsasii workflows gsasii.rietveld, gsasii.spf requires ==5.7.9
engine: not installed in this environment
topas workflows topas.rietveld, topas.spf requires ==6
engine: no installed version declared (topas_version / .powderline_config.yaml)
GSAS-II server: not running (state dir /tmp/powderline-1000)
no problems found
An engine that is not installed is not a problem: the core-only environment
runs no engine by design. Neither is a TOPAS version left undeclared. The
command lists each problem under PROBLEMS and exits non-zero when it finds
any of these:
no gateway at all: the install is stale (KI-13);
a gateway that fails to load;
an installed engine outside the version PowderLine supports;
an engine whose installed version cannot be read;
a
.powderline_config.yamlthat cannot be read, for the TOPAS settings.
Each problem line names what went wrong. For a stale install it also names the repair.
2. Use the GSAS-II server#
GSAS-II is loaded at the start of every run, and loading it takes time. The
GSAS-II server is a background process that keeps GSAS-II loaded, so a
series of runs pays that cost once. It serves only gsasii.* recipes.
flowchart TB
R["gsasii recipe"] --> M{"execution mode"}
M -- "auto or server" --> U{"server usable?<br/>running or started,<br/>and current"}
U -- yes --> SV["run in the server"]
U -- "no (auto)" --> IP["run in-process"]
U -- "no (server)" --> F["fail:<br/>ExecutionBackendError"]
M -- "in-process" --> IP
Mode |
Command line |
Python |
What happens |
|---|---|---|---|
auto (default) |
none |
|
uses the server, starting it if needed; runs in-process if the server cannot be used |
server |
|
|
uses the server, starting it if needed; fails if it cannot |
in-process |
|
|
never uses the server |
In-process means the refinement runs inside the process that called
PowderLine: the powderline command, or your Python script. GSAS-II is
loaded into that process for the run. In Python this mode is named
"subprocess", but no separate process is started.
All three modes give the same results and files. The command line prints
which one ran: Executed using server mode, or Executed using subprocess mode for an in-process run. In Python, result["method"] says "server"
or "subprocess" the same way.
When auto mode runs in-process#
In auto mode a run goes in-process when any of the following happens. The
result’s method then says subprocess, and the CLI prints
Executed using subprocess mode:
no server can be started, for example because a pinned port is busy;
a server it has just started is not answering yet. It goes on loading GSAS-II in the background, and the next run uses it;
the server is stale (see below);
the exchange with the server fails, for example a dropped connection or a reply that is not signed with your token.
A connection that cannot be made is retried twice, after 0.5 s and then
1 s, before the run gives up on the server. In server mode (--use-server), each of these cases
fails the run instead, with reason server_unavailable or
communication_failed.
A run never falls back in-process after a time limit (below). A run that
failed inside the server, for example with reason diverged, fails as it
would in-process. It is not run again.
Manage the server#
pixi run -e gsasii gsas-server status # running? its PID, URL, log file, and whether its code is current
pixi run -e gsasii gsas-server stop
pixi run -e gsasii gsas-server logs # the last 50 lines of its log
pixi run -e gsasii gsas-server start # runs the server in this terminal; the command does not return
pixi run -e gsasii gsas-server restart # stop, then start in this terminal; the command does not return
You rarely need start. A run in auto or server mode starts the server in
the background by itself.
The server keeps running after your run ends, until you stop it or the
computer restarts (KI-19). Stop it when you finish a session,
before you log out: pixi run -e gsasii gsas-server stop. On a shared
workstation where no one will stop it, switch the server off with
POWDERLINE_NO_SERVER (below).
Important
gsas-server start and gsas-server restart run the server in the
terminal you type them in. The command does not return while the server
runs, and its messages appear there. Stop it with Ctrl+C, or with
gsas-server stop from another terminal. Use them in a terminal of their
own, for example to watch the server start.
The server runs one refinement at a time. Requests from several of your processes wait their turn. Time spent waiting counts toward a time limit.
Restart it after an update#
The server loads PowderLine’s code once and keeps it. After you update
PowderLine (a git pull, another checkout), the running server still has
the old code. PowderLine detects this and calls the server stale:
gsas-server statusprintsCode: STALE;an auto-mode run prints
WARNING: the GSAS-II server is staleand runs in-process instead;a
--use-serverrun fails with reasonserver_unavailable.
Stop the stale server:
pixi run -e gsasii gsas-server stop
The next run in auto or server mode starts a current server in the
background. To start it yourself instead, run gsas-server start in a
terminal of its own.
Set a time limit#
By default a run waits for the server’s answer as long as it takes. To set a limit:
pixi run -e gsasii powderline my_sample/input.json --server-timeout 600
In Python, pass server_timeout=600. Past the limit the run fails with
ExecutionBackendError, reason timeout. It does not fall back to
running in-process: the job is still running in the server, and a second run
would double the work.
3. Run a batch of recipes#
A short Python script runs a folder of recipes and keeps going when one fails:
from pathlib import Path
import powderline
for path in sorted(Path("batch").glob("*/input.json")):
try:
recipe = powderline.load_recipe_asset(path)
result = powderline.run(recipe, path.parent / "output")
except (ValueError, powderline.PowderLineError) as exc:
reason = getattr(exc, "reason", type(exc).__name__)
print(f"{path}: not run ({reason})")
continue
print(f"{path}: {result['status']}, Rwp {result['rwp']}")
Run it in the engine’s environment: pixi run -e gsasii python batch.py.
In auto mode the first gsasii.* recipe starts the server and the rest
reuse it.
ValueError covers a recipe that cannot be read or does not validate.
PowderLineError covers every PowderLine error, including a failed run.
4. Run unattended#
Nothing in a failed run looks like a success:
A failed run raises
EngineExecutionError(the engine ran and failed) orExecutionBackendError(it never ran), with a.reasoncode.The command line prints the reason and exits with status 1. A successful run exits 0. So does a TOPAS run that only wrote its input (status
generated).The output directory of a failed run holds
failure.json, the full failure record, beside the engine’s own files. No result table is written.Each run first removes PowderLine’s own fixed-name result files from its output directory, so a reused directory holds one run’s results. This happens only once the recipe has validated and the engine is available. The engine’s own files and anything else in the directory stay.
A result can also succeed with warnings you should read, such as
gsasii_fit_not_converged or output_recipe_not_valid. Log
result["warnings"] with each run.
Use PowderLine from Python shows
how to catch and record failures.
Check:
pixi run -e gsasii gsas-server statussaysServer is runningandCode: current (matches this checkout).In a batch,
result["method"]is"server"for everygsasii.*run after the server has started. On the command line, such a run printsExecuted using server mode.
Next: Run a series, Troubleshoot.