# User Guide

## Overview

PrecipGen provides a unified, enhanced API with seamless workflow integration capabilities:

1. **Enhanced Unified API** - All components accessible through single import (recommended)
2. **Decoupled Simulation Engines** - Parameter-only operation without historical data requirements
3. **Comprehensive Analytics** - Enhanced plotting and trend analysis capabilities
4. **Seamless Workflows** - From CSV/GHCN data through analysis to simulation

## Enhanced Unified API

### Complete CSV to Simulation Workflow

For immediate analysis with CSV data:

```python
import precipgen as pg

# Enhanced CSV loading with metadata preservation
precip_data = pg.load_csv_precipitation_data(
    "Logan_UT.csv",
    station_name="Logan, UT",
    coordinates=(41.7370, -111.8338)
)

# Enhanced analytical engine with comprehensive capabilities
engine = pg.AnalyticalEngine(precip_data, wet_day_threshold=0.0254)
engine.initialize()

# Comprehensive statistics and visualization
engine.print_annual_precipitation_statistics()
engine.plot_annual_precipitation(save_path='annual_precip.png')
engine.plot_trend_analysis(save_path='trends.png')

# Generate parameter manifest
manifest = engine.generate_parameter_manifest()

# Parameter-only simulation (no historical data required)
simulator = pg.PrecipitationSimulator(parameters=manifest)
results = simulator.run_monte_carlo_simulation(
    start_date='2025-01-01',
    end_date='2030-12-31',
    n_realizations=100,
    methods=['wgen']
)

print(f"✓ Generated {results['wgen'].shape[1]} realizations of synthetic data")
```

### GHCN to Full Simulation Workflow

For GHCN station-based analysis:

```python
import precipgen as pg

# GHCN workflow (now properly accessible)
workflow = pg.GHCNWorkflow(station_id="USC00425186")
historical_data = workflow.load_historical_data()

# Enhanced analysis with same tools
engine = pg.AnalyticalEngine(historical_data, wet_day_threshold=0.0254)
engine.initialize()
manifest = engine.generate_parameter_manifest()

# Full simulation with both WGEN and bootstrap methods
simulator = pg.PrecipitationSimulator(
    parameters=manifest, 
    historical_data=historical_data
)
results = simulator.run_monte_carlo_simulation(
    start_date='2025-01-01',
    end_date='2030-12-31',
    methods=['wgen', 'bootstrap_doy'],
    n_realizations=50
)

print(f"Methods available: {list(results.keys())}")
```

### Synthetic Data Analysis

Analyze synthetic data with same analytical tools:

```python
# Analyze synthetic data with same tools as historical data
synthetic_data = results['wgen'].iloc[:, 0]  # First realization

synthetic_engine = pg.AnalyticalEngine(synthetic_data, wet_day_threshold=0.0254)
synthetic_engine.initialize()
synthetic_engine.print_annual_precipitation_statistics()
synthetic_engine.plot_annual_precipitation(save_path='synthetic_annual.png')
```

### Advanced Workflow Integration

Use the enhanced workflow integration API:

```python
from precipgen.api.workflow_integration import WorkflowIntegrator

# Automated workflow with caching and optimization
integrator = WorkflowIntegrator(enable_caching=True)

results = integrator.create_integrated_workflow(
    data_source="precipitation.csv",
    analysis_config={'wet_day_threshold': 0.0254},
    simulation_config={'n_realizations': 100, 'methods': ['wgen']}
)

if results['success']:
    print(f"✓ Complete workflow: {results['simulation_results']['wgen'].shape}")
```

## Enhanced Core API

### Decoupled Parameter-Only Simulation

For expert control with parameter-only operation:

```python
import precipgen as pg

# Load and analyze data
precip_data = pg.load_csv_precipitation_data("precipitation.csv")
engine = pg.AnalyticalEngine(precip_data, wet_day_threshold=0.1)
engine.initialize()

# Generate parameters
manifest = engine.generate_parameter_manifest()

# Parameter-only simulation (decoupled from historical data)
simulator = pg.PrecipitationSimulator(parameters=manifest)
results = simulator.run_monte_carlo_simulation(
    start_date='2025-01-01',
    end_date='2030-12-31',
    n_realizations=50,
    methods=['wgen']  # Parameter-only methods
)

print(f"Simulation shape: {results['wgen'].shape}")
```

### Enhanced Analytical Capabilities

Access comprehensive analysis features:

```python
# Enhanced analytical engine
engine = pg.AnalyticalEngine(precip_data, wet_day_threshold=0.0254)
engine.initialize()

# Comprehensive annual statistics
stats = engine.get_annual_precipitation_statistics()
print(f"Mean annual precipitation: {stats['mean_annual_total']:.1f} mm")
print(f"Wet day frequency: {stats['wet_day_frequency']:.3f}")

# Trend analysis with significance testing
trend = engine.analyze_annual_precipitation_trend()
print(f"Annual trend: {trend['slope']:.2f} mm/year (p={trend['p_value']:.3f})")

# Enhanced plotting with automatic station names
engine.plot_annual_precipitation(save_path='annual_precip.png')
engine.plot_trend_analysis(save_path='trends.png')
```

### Standardized API

For external integration and programmatic access:

```python
from precipgen.api import StandardizedAPI
import pandas as pd

# Load precipitation data
precip_data = pd.read_csv("precipitation.csv", index_col=0, parse_dates=True)['precipitation']

# Initialize API
api = StandardizedAPI()

# Complete analysis with single function call
result = api.analyze_data(
    data=precip_data,
    analysis_config={
        'wet_day_threshold': 0.0254,  # 0.001 inches in mm
        'window_years': 30
    }
)

if result['success']:
    print("Analysis completed successfully!")
    
    # Access results
    monthly_params = result['monthly_parameters']
    trend_analysis = result['trend_analysis']
    
    # Display sample parameters
    january = monthly_params[1]
    print(f"January: P(W|W)={january['p_ww']:.3f}, P(W|D)={january['p_wd']:.3f}")
    
    # Test with simulation
    sim_result = api.create_simulation_engine(result['parameter_manifest'], random_seed=42)
    if sim_result['success']:
        engine_id = sim_result['engine_id']
        
        # Generate synthetic data
        batch_result = api.run_simulation_batch(engine_id, num_steps=365)
        if batch_result['success']:
            synthetic_values = batch_result['values']
            print(f"Generated {len(synthetic_values)} days of synthetic precipitation")
```

### Batch Processing

Analyze multiple locations:

```python
from precipgen.convenience import SimpleBatchProcessor

processor = SimpleBatchProcessor(max_workers=4)
locations = [
    "Seattle, WA",
    "Portland, OR", 
    "San Francisco, CA",
    "Los Angeles, CA"
]

results = processor.analyze_multiple_locations(locations)

# Check results
summary = results['summary']
print(f"Success rate: {summary['success_rate']:.1%}")
print(f"Processing time: {summary['processing_time']:.1f}s")

# Access individual results
for location, result in results['results'].items():
    print(f"{location}: {result['station_name']}")
```

## Core API

### Enhanced Parameter Extraction

For expert control and integration:

```python
import precipgen as pg

# Load precipitation data with enhanced CSV loader
precip_data = pg.load_csv_precipitation_data(
    "precipitation.csv",
    station_name="Custom Station",
    coordinates=(40.0, -111.0)
)

# Enhanced analytical engine
engine = pg.AnalyticalEngine(precip_data, wet_day_threshold=0.1)
engine.initialize()

# Calculate monthly parameters with enhanced metadata
monthly_params = engine.calculate_monthly_parameters()
manifest = engine.generate_parameter_manifest()

# Access parameters for each month
for month, params in monthly_params.items():
    print(f"Month {month}: P(W|W)={params.p_ww:.3f}, "
          f"P(W|D)={params.p_wd:.3f}")

# Enhanced metadata available
print(f"Station: {manifest.metadata.get('station_name', 'Unknown')}")
print(f"Analysis date: {manifest.metadata.get('analysis_date', 'Unknown')}")
```

### Enhanced Trend Analysis

Detect climate shifts with comprehensive analysis:

```python
# Enhanced trend analysis with statistical significance
trend_analysis = engine.analyze_annual_precipitation_trend()

print(f"Annual precipitation trend:")
print(f"  Slope: {trend_analysis['slope']:.2f} mm/year")
print(f"  R-squared: {trend_analysis['r_squared']:.3f}")
print(f"  P-value: {trend_analysis['p_value']:.3f}")
print(f"  Significance: {trend_analysis['significance']}")

# Comprehensive trend report with visualizations
report = engine.generate_comprehensive_trend_report(
    window_years=30,
    save_plots=True,
    output_dir='trend_analysis'
)

print(f"Trend report generated with {len(report['plots_created'])} plots")
```

### Decoupled Synthetic Data Generation

Generate precipitation sequences with enhanced simulation engine:

```python
# Create parameter-only simulator (no historical data required)
simulator = pg.PrecipitationSimulator(parameters=manifest)

# Validate parameters before simulation
validation = simulator.validate_parameters()
if validation['is_valid']:
    print("✓ Parameters validated successfully")
else:
    print("✗ Parameter validation failed:")
    for error in validation['errors']:
        print(f"  - {error}")

# Generate synthetic data with Monte Carlo simulation
results = simulator.run_monte_carlo_simulation(
    start_date='2025-01-01',
    end_date='2030-12-31',
    n_realizations=100,
    methods=['wgen'],
    seed=42
)

print(f"Generated synthetic data: {results['wgen'].shape}")
print(f"Mean annual precipitation: {results['wgen'].sum().mean():.1f} mm")
```

### Data Validation

Ensure research-grade data quality:

```python
from precipgen import DataValidator

validator = DataValidator()
validation_result = validator.validate_data(precip_series)

if validation_result.is_valid:
    print("✓ Data passes quality checks")
    print(f"Completeness: {validation_result.metrics['completeness']:.1%}")
else:
    print("✗ Data quality issues:")
    for error in validation_result.errors:
        print(f"  - {error}")
```

## Configuration

### Analysis Configuration

Customize analysis parameters:

```python
from precipgen.config import AnalysisConfig

config = AnalysisConfig(
    min_years_data=25,           # Require 25+ years
    wet_day_threshold=0.1,       # 0.1mm threshold
    trend_window_years=30,       # 30-year sliding window
    significance_level=0.01,     # 99% confidence
    parallel_execution=True      # Enable parallel processing
)

# Validate configuration
errors = config.validate()
if errors:
    print("Configuration errors:")
    for error in errors:
        print(f"  - {error}")
```

### Station Requirements

Control station discovery:

```python
from precipgen.config import StationRequirements

requirements = StationRequirements(
    min_years=30,                # 30+ years required
    max_distance_km=100.0,       # Search within 100km
    min_completeness=0.9,        # 90% data completeness
    preferred_distance_km=25.0   # Prefer stations within 25km
)
```

## Data Structures

### Analysis Results

The `SimpleAnalysisResult` contains:

```python
result = quick_analysis("Seattle, WA")

# Station information
print(result.station_id)        # GHCN station ID
print(result.station_name)      # Station name
print(result.coordinates)       # (lat, lon) tuple
print(result.data_years)        # Years of data

# Parameter manifest (core WGEN parameters)
manifest = result.parameter_manifest
monthly_params = manifest.overall_parameters  # Dict[int, MonthlyParams]

# Trend analysis (if available)
if result.trend_analysis:
    slopes = result.trend_analysis['seasonal_slopes']
    significance = result.trend_analysis['significance_tests']

# Validation summary
validation = result.validation_summary
print(validation['data_completeness'])
print(validation['parameter_quality_score'])
```

### Monthly Parameters

Each month's WGEN parameters:

```python
january = monthly_params[1]  # January parameters

print(f"P(W|W): {january.p_ww}")    # Wet-to-wet transition probability
print(f"P(W|D): {january.p_wd}")    # Dry-to-wet transition probability  
print(f"Alpha: {january.alpha}")    # Gamma shape parameter
print(f"Beta: {january.beta}")      # Gamma scale parameter

# Convert to dictionary
params_dict = january.to_dict()
```

## Best Practices

### Error Handling

Always handle potential errors:

```python
from precipgen.utils.exceptions import PrecipGenError, InsufficientDataError

try:
    result = quick_analysis("Remote Location")
except InsufficientDataError as e:
    print(f"Not enough data: {e}")
except PrecipGenError as e:
    print(f"Analysis failed: {e}")
```

### Performance

For large datasets or batch processing:

```python
# Use parallel processing
config = AnalysisConfig(parallel_execution=True, max_workers=4)

# Process in batches
locations = ["City1", "City2", ...]  # Large list
batch_size = 10

for i in range(0, len(locations), batch_size):
    batch = locations[i:i+batch_size]
    results = processor.analyze_multiple_locations(batch)
    # Process results...
```

### Reproducibility

For reproducible results:

```python
import numpy as np

# Set random seed before simulation
np.random.seed(42)
result = quick_analysis("Seattle, WA")

# Save results for later
result_dict = result.to_dict()
with open("seattle_analysis.json", "w") as f:
    json.dump(result_dict, f, indent=2)
```

## Integration

### External Models

PrecipGen is designed for integration:

```python
from precipgen.api import StandardizedAPI

# Use standardized interface for external integration
api = StandardizedAPI()
config_dict = api.get_configuration()
parameter_dict = api.extract_parameters(data)

# State-based simulation for coupling
state = api.initialize_simulation(parameter_dict)
for timestep in range(1000):
    precip, state = api.step_simulation(state)
    # Pass precip to your hydrological model...
```

### Custom Workflows

Combine simplified and core APIs:

```python
from precipgen import SimplePrecipGen, AnalyticalEngine

# Use simplified API for station discovery
api = SimplePrecipGen()
station_info = api._find_best_station("Seattle, WA", 25, 50.0)

# Use core API for custom analysis
engine = AnalyticalEngine(your_custom_data)
parameters = engine.calculate_monthly_parameters()

# Combine results as needed...
```

## Next Steps

- See [API Reference](api.md) for complete function documentation
- See [Mathematical Foundation](mathematical_foundation.md) for algorithm details
- Check [examples/](../examples/) for complete working examples