PowderLine uses pixi for reproducible conda environments:
# Install dependencies (first time) pixi install # Activate environment pixi shell
Run a refinement from a JSON recipe:
pixi run kicker examples/example_LaB6/input.json
Validate a recipe without running refinement:
pixi run kicker --validate-only examples/example_LaB6/input.json
Enable verbose output:
pixi run kicker --verbose examples/example_LaB6/input.json
The same JSON recipe can be driven through TOPAS v7 (Bruker), not just GSAS-II.
The TOPAS path imports zero GSAS-II, so it runs with no GSAS-II installed at
all. Translate a GSASII_Rietveld or GSASII_SPF
recipe into a TOPAS v7 .inp + .xye pair:
pixi run topas-kicker examples/example_LaB6/input.json
This writes <name>.inp and <name>.xye under
examples/<name>/output/topas/; if tc.exe is discoverable it also runs the
refinement and parses the results into the same standardized reports the GSAS-II
path produces. Use --output DIR to choose a directory, --validate-only to
check translatability without writing files, and --topas-dir /
--topas-version to locate tc.exe.
From Python, select the engine with a single flag:
import powderline result = powderline.run(recipe, output_dir, engine="topas") # vs engine="gsasii"
A third engine, open-source easydiffraction, is available as
engine="easydiffraction" after installing the optional pixi environment
(pixi install -e easydiff; easydiffraction needs Python ≥3.12, the default
environment is untouched). It consumes the same recipes and returns the same
result dictionary — see the integration guide's easydiffraction section for
its v1 capability list.
engine="topas" returns the same result dictionary as the GSAS-II engine
(plus rwp/r_exp/gof). All 8 real example recipes translate and have
been validated against a real tc.exe run on Windows (the 9th,
example_template, is a fill-in-the-blanks skeleton and is rejected with a
clear error by design). Refined lattice parameters agree with GSAS-II to
sub-percent across the example set; correlated profile terms (instrument
U..Z, size vs. strain) are not individually comparable between engines, but
cell, scale, and occupancy are reliable.
Execute the test suite:
pixi run test
Or with pytest directly:
pixi run pytest -v
A PowderLine recipe is a JSON file describing refinement parameters (Schema 0.26.0). All examples use schema 0.26.0 file-less payloads with embedded data.
{
"schema_name": "GSASII_Rietveld",
"schema_version": "0.26.0",
"payload": {
"xrd_data": {
"tth": [10.0, 10.5, 11.0],
"Itth": [1234.5, 1230.2, 1228.9],
"Itth_weights": [1.0, 1.0, 1.0]
},
"instrument": {
"description": "28-ID-2",
"initialization": [
{},
{}
],
"parameterization": {
"wavelength": [0.45236, false, null, null],
"broadening": {
"U": [0.01, true, null, null],
"V": [-0.005, true, null, null],
"W": [0.002, true, null, null]
}
}
},
"phases": {
"MyPhase": {
"structure": {
"phase_name": "MyPhase",
"space_group": "P m -3 m",
"unit_cell": {
"a": 4.157,
"b": 4.157,
"c": 4.157,
"alpha": 90.0,
"beta": 90.0,
"gamma": 90.0,
"volume": 71.83
},
"atoms": {
"La": {
"element": "La",
"x": 0.0,
"y": 0.0,
"z": 0.0,
"occupancy": 1.0,
"ADP": "Uiso",
"Uiso": 0.008,
"Multiplicity": 1
}
}
},
"parameterization": {
"scale": [1.0, true, null, null]
}
}
},
"refinement_controls": {
"refinement_cycles": 5
}
}
}See examples/ directory for complete working examples.
After refinement, PowderLine generates standardized outputs with fixed filenames (Schema 0.26.0):
GSAS-II files:
dummy.gpx- GSAS-II project file (reopenable in GUI)dummy.lst- Human-readable refinement log with Rwp and parameter tables
Refinement results:
refined_parameters.csv- All refined parameters with ESDs (9 columns):parameter_name: GSAS-II internal identifierdescriptive_name: Human-readable descriptionphase_name,phase_idx: Phase associations (null for non-phase parameters)atom_name,atom_idx: Atom associations (null for non-atom parameters)value: Refined parameter valueesd: Estimated standard deviation from covariance matrixcategory: Parameter classification (instrument, background, cell, atom_position, etc.)
<phase>_unit_cell_report.csv- Unit cell parameters with ESDs (3 columns per phase):parameter: a, b, c, alpha, beta, gamma, volumevalue: Refined unit cell parameteresd: Estimated standard deviation
<phase>_peak_list_report.csv- Reflection list (hkl, d-spacing, 2θ, intensities per phase)fit_profile.txt- Observed/calculated/background/difference intensities
Single peak fitting (SPF) mode additional files:
single_peaks_report.txt- Peak fit results (position, width, intensity)peak_convergence_diagnostics.txt- Convergence warnings
Note: Simulation mode (all refine_flag=false) does not generate refined_parameters.csv since no parameters are refined.
powderline.run() is the main Python entry point. It validates the recipe,
dispatches to the GSAS-II server (or falls back to in-process execution), and
returns results as pandas DataFrames.
import json
from pathlib import Path
import powderline
recipe_path = Path("examples/example_LaB6/input.json")
recipe = json.loads(recipe_path.read_text())
output_dir = Path("/tmp/powderline_out")
output_dir.mkdir(exist_ok=True)
result = powderline.run(recipe, output_dir)Normal refinement — result keys:
result['success'](bool): True if refinement convergedresult['rwp'](float): Weighted profile R-factorresult['elapsed_time'](float): Wall-clock secondsresult['fit_profile'](DataFrame): Observed/calculated/background/difference intensity columnsresult['unit_cell_data'](dict[str, DataFrame]): Per-phase unit cell parameters and ESDs, keyed by phase nameresult['peak_list_data'](dict[str, DataFrame]): Per-phase hkl reflection lists, keyed by phase nameresult['refined_parameters'](DataFrame): 9-column parameter table with ESDsresult['spf_peaks'](DataFrame): SPF peak positions, widths, intensities; empty for Rietveldresult['spf_convergence_diagnostics'](DataFrame): SPF convergence warnings; empty for Rietveldresult['output_files'](list[str]): Paths of all written output files
Validate-only mode (no refinement executed):
result = powderline.run(recipe, output_dir, validate_only=True)
# result keys: success, rwp (None), elapsed_time, method ('validate_only'),
# schema_name, schema_version, phases, refinement_cycles, simulation_modeSPF DataFrame example:
result = powderline.run(spf_recipe, output_dir)
df = result['spf_peaks']
# Columns: position_2theta, intensity, sigma, sigma_squared, gamma,
# fwhm_gaussian, fwhm_lorentzian, fwhm_pseudovoigt,
# integral_breadth_gaussian, integral_breadth_lorentzian,
# integral_breadth_pseudovoigt, fwhm_gsas_verification,
# converged, convergence_detailExecution mode control:
result = powderline.run(recipe, output_dir, execution_mode='auto') # default: try server, fall back to subprocess
result = powderline.run(recipe, output_dir, execution_mode='server') # require the HTTP server
result = powderline.run(recipe, output_dir, execution_mode='subprocess') # in-process execution- Read :doc:`DEVELOPMENT` for comprehensive project understanding
- Explore examples in
examples/directory - Consult :doc:`TROUBLESHOOTING` if you encounter issues
- See :doc:`api` for detailed function documentation