Skip to content

Latest commit

 

History

History
258 lines (196 loc) · 8.84 KB

File metadata and controls

258 lines (196 loc) · 8.84 KB

Getting Started

Installation

PowderLine uses pixi for reproducible conda environments:

# Install dependencies (first time)
pixi install

# Activate environment
pixi shell

Basic Usage

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

Running a recipe through TOPAS v7 instead of GSAS-II

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.

Running Tests

Execute the test suite:

pixi run test

Or with pytest directly:

pixi run pytest -v

Recipe Structure

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.

Output Files

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 identifier
    • descriptive_name: Human-readable description
    • phase_name, phase_idx: Phase associations (null for non-phase parameters)
    • atom_name, atom_idx: Atom associations (null for non-atom parameters)
    • value: Refined parameter value
    • esd: Estimated standard deviation from covariance matrix
    • category: 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, volume
    • value: Refined unit cell parameter
    • esd: 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.

Programmatic API

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 converged
  • result['rwp'] (float): Weighted profile R-factor
  • result['elapsed_time'] (float): Wall-clock seconds
  • result['fit_profile'] (DataFrame): Observed/calculated/background/difference intensity columns
  • result['unit_cell_data'] (dict[str, DataFrame]): Per-phase unit cell parameters and ESDs, keyed by phase name
  • result['peak_list_data'] (dict[str, DataFrame]): Per-phase hkl reflection lists, keyed by phase name
  • result['refined_parameters'] (DataFrame): 9-column parameter table with ESDs
  • result['spf_peaks'] (DataFrame): SPF peak positions, widths, intensities; empty for Rietveld
  • result['spf_convergence_diagnostics'] (DataFrame): SPF convergence warnings; empty for Rietveld
  • result['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_mode

SPF 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_detail

Execution 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

Next Steps