# PYSQ - Siroquant SDK for Python

Python SDK for Siroquant V5 API.

Website: [https://www.siroquant.com/](https://www.siroquant.com/)

>**Siroquant** is a commercial software package designed for quantitative phase analysis using X-ray diffraction (XRD) data, primarily through the Rietveld refinement method. It enables users to determine the composition of crystalline materials—such as minerals, cements, coals, and clays—by fitting full XRD powder patterns without needing physical standards, making it a standardless technique.

## Getting Started

```bash
# create a virtual environment and activate it
python -m venv venv
source venv\Scripts\activate

# Install the package
pip install pysq

# Update the package (optional)
pip install --upgrade pysq
```

## Usage Examples

### Simple Example

```python
from pysq import SQAPI, SQAPIConfig

config = SQAPIConfig(lib_dir=r".\lib", dll_path=r".\lib\sq_api.dll")

with SQAPI(config) as sq:
    sq.initialize()
    task_info = sq.open_task("task.tsk")
    results = sq.refine(task_info.job_handle)
    print(f"Results: {results}")
```

### Advanced Example

```python
from pysq import SQAPI, SQAPIConfig, SQAPIError, RefinementParams, ReportResultsFlags, SaveTaskFlags, TaskContext

TASK_FILE = r".\tasks\demo.tsk"
LIB_DIR   = r".\lib"
DLL_PATH  = r".\lib\sq_api.dll"


def main() -> None:
    config = SQAPIConfig(lib_dir=LIB_DIR, dll_path=DLL_PATH)

    try:
        with SQAPI(config) as sq:
            sq.initialize()

            with TaskContext(sq, TASK_FILE) as (job_handle, task_info):
                print(f"Task: {task_info}")

                params = RefinementParams(
                    n_auto_prescale=1,
                    n_refs=1,
                    cutoff=0.5,
                    error_cutoff=1.0,
                    error_pc=0.75,
                    flags=0,
                ) # pass None to use the task's stored configuration
                results = sq.refine(job_handle, params=params, report_flags=ReportResultsFlags.CORRECTED)

                print(f"\nResults: {results}")
                if results.phases:
                    print(f"\n{'No.':<4} {'Phase Name':<20} {'Weight (%)':<12} {'Error (%)':<10}")
                    print("-" * 50)
                    for i, phase in enumerate(results.phases, 1):
                        print(f"{i:<4} {phase.phase_name:<20} {phase.weight_pc:<12.2f} {phase.error_of_fit:<10.2f}")

                sq.save_task(job_handle)
                print(f"\nTask saved to: {TASK_FILE}")

    except SQAPIError as e:
        print(f"\nSQ API Error: {e}")
        if e.error_code is not None:
            print(f"  Code: {e.error_code}")
    except Exception as e:
        print(f"\nError: {e}")


if __name__ == "__main__":
    main()
```

## Configuration

Set paths via environment variables or code:

- `SQ_LIB_DIR`: Library directory path
- `SQ_DLL_PATH`: DLL path (optional, auto-detected)

## Requirements

- Python 3.8+
- Windows (x64)
- Siroquant V5
