Metadata-Version: 2.1
Name: prismWriter
Version: 1.5.0
Summary: Python library for programmatically creating and manipulating GraphPad Prism (.pzfx) files
Author: smestern
License: MIT License
        
        Copyright (c) 2024 smestern
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/smestern/prismWriter
Project-URL: Repository, https://github.com/smestern/prismWriter
Project-URL: Documentation, https://github.com/smestern/prismWriter#readme
Project-URL: Bug Tracker, https://github.com/smestern/prismWriter/issues
Keywords: graphpad,prism,pzfx,data visualization,scientific,pandas
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.20
Requires-Dist: pandas>=1.3
Requires-Dist: openpyxl>=3.0
Provides-Extra: gui
Requires-Dist: PySide6>=6.5; extra == "gui"
Provides-Extra: web
Requires-Dist: streamlit>=1.20; extra == "web"
Provides-Extra: all
Requires-Dist: PySide6>=6.5; extra == "all"
Requires-Dist: streamlit>=1.20; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"

# prismWriter

Python library and GUI for programmatically creating and manipulating GraphPad Prism (`.pzfx`) files. Convert pandas DataFrames into Prism's XML-based table format with complex grouping structures.

**Version:** 1.0.0

## Features

- Convert pandas DataFrames to GraphPad Prism format
- Flexible grouping: main groups, sub-columns, row labels
- Multiple interfaces: Python API, Qt GUI, and Streamlit Web interface
- Load and modify existing `.pzfx` files
- Validate table structure with preview functionality
- Automatic backup creation when loading existing files

## Installation

```bash
pip install -e .
```

### Requirements

- Python >= 3.7
- numpy
- pandas
- openpyxl (for Excel file support)
- PySide6 (for Qt GUI) [optional]
- streamlit >= 1.28.0 (for web interface) [optional]


### See Also:

- https://github.com/Yue-Jiang/pypzfx - Another python package with similar functionality
- https://github.com/Biomiha/prism2R - R package for reading .prism (newer) files
- https://github.com/yue-jiang/pzfx - R package for reading .pzfx files

## Quick Start

### Python API

```python
from prismWriter.prism_writer import PrismFile
import pandas as pd

# Create a new PrismFile
pf = PrismFile()

# Load your data
df = pd.read_csv('data.csv')

# Create a grouped table
pf.make_group_table(
    group_name="MyTable",
    group_values=df,
    groupby="condition",  # Main grouping column
    cols=["value1", "value2"],  # Data columns
    subgroupby="replicate"  # Sub-grouping
)

# Save to Prism file
pf.save("output.pzfx")
```

### Web Interface (Streamlit)

The easiest way to use prismWriter:

```bash
streamlit run prismWriter/streamlit_app.py
```

Or use the provided launch script:
- **Windows**: `run_web.bat`

Or after installation:
```bash
prismwriter-web
```

Features:
- Upload CSV/Excel files (with multi-sheet Excel support)
- Live data preview with automatic column type detection
- Interactive grouping configuration
- Preview table structure before generating
- Direct download of generated `.pzfx` files
- Load and view existing Prism files

### Qt GUI

```bash
python prismWriter/gui.py
```

Or after installation:
```bash
prismwriter-gui
```

## API Reference

### PrismFile Class

```python
pf = PrismFile(file=None)  # Create new or load existing file
```

**Methods:**
- `load(file_path, backup=True)` - Load an existing Prism file
- `smake_group_table(group_name, group_values, groupby=None, cols=None, subgroupby=None, rowgroupby=None, append=True)` - Create a grouped table
- `get_table_names()` - Get list of all table names
- `to_dataframe(table_name)` - Convert a table to pandas DataFrame
- `save(file_path)` - Save to file
- `write(file_path, xml_declaration=True, encoding='utf-8', pretty_print=True)` - Write with options
- `remove_table(table_name)` - Remove a table from the file

### Grouping Parameters

- **`groupby`**: Main column grouping - creates separate Y-columns for each category
- **`subgroupby`**: Sub-columns within each Y-column (string for column name, or list for data columns)
- **`rowgroupby`**: Row labels on the vertical axis (string for column name, or list for data columns)
- **`cols`**: Data columns to include

**Note**: Use either column name (`subgroupby='condition'`) OR list of data columns (`subgroupby=['col1', 'col2']`) - not both.

### Example Data Structure

```python
import pandas as pd
from prismWriter.prism_writer import PrismFile

# Sample data
data = {
    'treatment': ['Control', 'Control', 'Drug A', 'Drug A'],
    'time': [0, 24, 0, 24],
    'replicate': [1, 1, 1, 1],
    'value': [10.5, 15.2, 12.1, 25.8]
}
df = pd.DataFrame(data)

# Create Prism file
pf = PrismFile()
pf.make_group_table(
    group_name="Treatment_Data",
    group_values=df,
    groupby="treatment",    # Separate columns for Control vs Drug A
    rowgroupby="time",      # Rows labeled by timepoint
    cols=["value"]          # Data column
)
pf.save("treatment_data.pzfx")
```

## Loading Existing Files

```python
from prismWriter.prism_writer import PrismFile

# Load existing Prism file (creates automatic backup)
pf = PrismFile()
pf.load("existing.pzfx")

# Or load directly in constructor
pf = PrismFile(file="existing.pzfx")

# Get table names
tables = pf.get_table_names()
print(f"Found tables: {tables}")

# Convert table to DataFrame
df = pf.to_dataframe("TableName")

# Add new table
pf.make_group_table(
    group_name="NewTable",
    group_values=df,
    groupby="category",
    cols=["value"]
)

# Save (use write() for more options)
pf.save("modified.pzfx")
```

## Dependencies

- **Core**: pandas, numpy
- **GUI**: PySide6 (Qt bindings)
- **Web**: streamlit >= 1.28.0
- **Files**: openpyxl for Excel support

## Project Structure

```
prismWriter/
├── prismWriter/
│   ├── __init__.py          # Package exports
│   ├── prism_writer.py      # Core XML generation engine
│   ├── gui.py               # PySide6 Qt GUI wrapper
│   ├── streamlit_app.py     # Streamlit web interface
│   ├── prism_template2.pzfx # XML structure template
│   └── schema/              # Prism XML schemas
├── tests/
│   ├── test_prism_writer.py
│   ├── test_gui.py
│   └── test_data.csv
├── pyproject.toml
└── README.md
```

## Development

### Running Tests

```bash
pytest tests/
```

### Key Implementation Details

- Uses `prism_template2.pzfx` as XML structure blueprint
- XML Namespace: `{http://graphpad.com/prism/Prism.htm}`
- "Raveling" strategy: transforms DataFrames into flat structure via `melt()`, then rebuilds into nested XML hierarchy
- Automatic backup files created as `{filename}.backup{timestamp}` when loading existing files
- Logging enabled at INFO level for debugging table creation

## Known Limitations

- No validation for duplicate table names
- Row mismatch warnings can occur with sparse data
- Template system hardcoded to specific Prism XML schema version
- No undo functionality - backup files are the safety net

## Roadmap

- Add support for other table types (X-Y, nested, Multi var?)
- Add support for `.prism` loading (maybe saving?)

## License

MIT License

## Contributing

Contributions welcome! Please feel free to submit a Pull Request.
