Files
2025-11-30 09:08:49 +08:00

305 lines
8.0 KiB
Markdown

# Reading Current Prism Data State
## The Problem
Prism scripts **cannot read data values** into variables or use them for conditional logic. This is a fundamental limitation of the scripting language.
**What you CANNOT do:**
- Read a cell value into a variable
- Use if/else conditionals based on data
- Make script decisions based on analysis results
- Loop until a condition is met
- Compare values or perform calculations in the script
**The only "read" command** is `SetValueToInfo`, which copies a value from one location to another but doesn't let you use it in logic.
## The Solution: PZFX XML Files
Since Prism's scripting language can't read data, use the **PZFX file format** instead.
### What is PZFX?
- **PZFX** = Prism's XML file format
- Plain text XML structure (human and machine readable)
- **Data tables**: Fully readable and editable in XML
- **Info tables**: Fully readable and editable in XML
- **Analysis results**: Encrypted but readable as XML
- **Graph/analysis settings**: Encrypted (not editable externally)
### How Prism Automation Works
```
Prism's Built-in Automation:
Data → Auto-updates → Graphs
Data → Auto-updates → Analyses
Data → Auto-updates → Paste-linked tables
```
When you edit data in a PZFX file externally, Prism sees it as a data change and **auto-updates everything**.
## Workflow Patterns
### Pattern 1: Read-Only Analysis (Python/R)
**Use case**: Extract data/results for external analysis
```python
# Python example
import xml.etree.ElementTree as ET
# Read PZFX file
tree = ET.parse('experiment.pzfx')
root = tree.getroot()
# Extract data from table
for table in root.findall('.//Table'):
table_name = table.get('ID')
# Parse data cells
for cell in table.findall('.//d'):
value = cell.text
# Analyze, plot, whatever you need
```
### Pattern 2: Modify Data, Let Prism Analyze
**Use case**: Pre-process data externally, let Prism do analysis/graphing
```python
# Python example
import xml.etree.ElementTree as ET
# 1. Read PZFX template
tree = ET.parse('template.pzfx')
# 2. Modify data in XML
for table in tree.findall('.//Table[@ID="Data 1"]'):
# Update cell values
cells = table.findall('.//d')
cells[0].text = str(new_value)
# 3. Save modified file
tree.write('processed.pzfx')
# 4. Open in Prism - graphs/analyses auto-update!
```
### Pattern 3: Conditional Logic + Prism Script
**Use case**: Make decisions based on data, then run appropriate Prism script
```python
# Python: Read data and decide what to do
tree = ET.parse('results.pzfx')
p_value = float(tree.find('.//Cell[@Row="5"][@Col="3"]').text)
if p_value < 0.05:
script_to_run = "significant.pzc"
else:
script_to_run = "not_significant.pzc"
# Launch appropriate Prism script
import subprocess
subprocess.run(['prism', script_to_run])
```
### Pattern 4: Full Integration (Python + Prism)
**Complete workflow**:
```python
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
import subprocess
import os
# 1. Prepare data externally
data = process_experimental_data()
# 2. Create/modify PZFX file
tree = ET.parse('template.pzfx')
# ... populate data in XML ...
tree.write('experiment.pzfx')
# 3. Run Prism script to generate graphs
subprocess.run(['prism', '@export_graphs.pzc'])
# 4. Read results back from PZFX
tree = ET.parse('experiment.pzfx')
results = extract_results(tree)
# 5. Make decisions, generate reports
if results['significant']:
generate_report(results)
```
## Platform-Specific Integration
### macOS Approach
**Problem**: AppleScript can only launch Prism scripts, not read data.
**Solution**: Use PZFX + external tool
```applescript
-- Save current work (user does this manually or via script)
tell application "Prism"
-- Prism must already have file open, saved as PZFX
end tell
-- Process with Python/R/etc
do shell script "python3 ~/scripts/analyze_prism.py"
-- Reopen in Prism (optional - user can do manually)
tell application "Prism"
activate
open POSIX file "/path/to/processed.pzfx"
end tell
```
### Windows Approach
**Same principle**, but can use VBA, PowerShell, or Python:
```vbnet
' Excel VBA example
Sub ProcessPrismData()
' 1. Tell Prism to save as PZFX
' (user must do manually or via Save command in script)
' 2. Parse XML (using MSXML2.DOMDocument)
Dim xmlDoc As Object
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
xmlDoc.Load "C:\Data\experiment.pzfx"
' 3. Read values
Dim pValue As Double
pValue = CDbl(xmlDoc.SelectSingleNode("//Cell[@Row='5']").Text)
' 4. Make decision
If pValue < 0.05 Then
Shell "C:\Prism\prism.exe @C:\Scripts\significant.pzc"
End If
End Sub
```
## XML Structure Reference
### Data Table Structure
```xml
<Table ID="Data 1" XFormat="none" YFormat="replicates">
<Title>Dose Response</Title>
<ColumnTitlesRow>
<d>Dose</d>
<d>Response</d>
</ColumnTitlesRow>
<YColumn>
<Title>Control</Title>
<Subcolumn>
<d>10.5</d>
<d>12.3</d>
<d>11.8</d>
</Subcolumn>
</YColumn>
</Table>
```
### Info Constants Structure
```xml
<InfoSequence>
<Ref ID="Info0" />
</InfoSequence>
<Info ID="Info0">
<Title>Experiment Details</Title>
<Constant>
<Name>Date</Name>
<Value>2024-01-15</Value>
</Constant>
<Constant>
<Name>Experimenter</Name>
<Value>Jane Smith</Value>
</Constant>
</Info>
```
## Complete Example: Batch Processing with Conditionals
```python
#!/usr/bin/env python3
"""
Process multiple data files through Prism with conditional logic.
Prism scripts can't do conditionals, so we use Python + PZFX.
"""
import xml.etree.ElementTree as ET
import subprocess
import glob
# 1. Process each data file
for data_file in glob.glob('data/*.csv'):
# 2. Read data to make decision
data = read_csv(data_file)
# 3. Choose appropriate Prism template based on data
if len(data) > 100:
template = 'large_dataset_template.pzfx'
else:
template = 'small_dataset_template.pzfx'
# 4. Load template and populate data
tree = ET.parse(template)
populate_prism_data(tree, data)
# 5. Save as new PZFX file
output_file = f'processed/{data_file}.pzfx'
tree.write(output_file)
# 6. Run Prism script to export graphs
# Script is simple: just exports graphs, no logic needed
subprocess.run(['prism', '@export_graphs.pzc', output_file])
# 7. Read results back if needed
tree = ET.parse(output_file)
results = extract_results(tree)
# 8. Store in database, generate report, etc.
save_to_database(results)
```
## Key Takeaways
1. **Prism scripts are write-only**: They can import/export but not read for logic
2. **PZFX is the read interface**: Use external tools to parse XML
3. **Prism auto-updates**: Changing data in PZFX updates graphs/analyses
4. **Hybrid approach**: External tool for logic, Prism script for automation
5. **XML is documented**: Use the schema files in `prism-xml-schema/` directory
## Tools for PZFX Processing
### Python
- `xml.etree.ElementTree` - Built-in XML parser
- `lxml` - More powerful XML processing
- `pandas` - Can read XML tables
### R
- `xml2` package - XML parsing
- `XML` package - Alternative parser
### Excel VBA
- `MSXML2.DOMDocument` - Microsoft's XML parser
### Command Line
- `xmllint` - Validate and query XML
- `xq` - jq for XML (requires installation)
## When to Use Each Approach
| Scenario | Best Approach |
|----------|---------------|
| Simple batch import | Prism script alone |
| Conditional processing | Python/R + PZFX |
| Read analysis results | Python/R + PZFX |
| Complex data prep | External tool → PZFX → Prism |
| Integration with LIMS | Python/R reads/writes PZFX |
| Decision trees | External tool, not Prism script |