Skip to content

Latest commit

 

History

History
428 lines (344 loc) · 10.9 KB

File metadata and controls

428 lines (344 loc) · 10.9 KB

AirMedSim Architecture

System Overview

AirMedSim is built as a modern web application with three main components:

  1. Simulation Engine (Python/SimPy) - Discrete-event simulation core
  2. Backend API (FastAPI) - RESTful API serving hospital data and simulation results
  3. Frontend (React/TypeScript) - Interactive visualization and playback

Architecture Diagram

┌─────────────────┐
│   React Frontend│
│   (Port 5173)   │
│                 │
│  - Interactive  │
│    Hospital Map │
│  - Simulation   │
│    Playback     │
│  - Metrics      │
│    Dashboard    │
└────────┬────────┘
         │ HTTP/REST
         ▼
┌─────────────────┐
│  FastAPI Backend│
│   (Port 8000)   │
│                 │
│  - Hospital API │
│  - Simulation   │
│    Results API  │
│  - Config API   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  SimPy Engine   │
│                 │
│  - Discrete-    │
│    Event Sim    │
│  - Resource     │
│    Management   │
│  - Event Queue  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   Data Layer    │
│                 │
│  - CMS Hospital │
│    Data         │
│  - Simulation   │
│    Results      │
│  - Cache (JSON) │
└─────────────────┘

Component Details

Frontend (React + TypeScript + Tailwind)

Key Technologies:

  • React 18 with functional components and hooks
  • TypeScript 5.6 for type safety
  • Vite for fast development and optimized builds
  • Tailwind CSS v3 for styling with custom theme
  • @vis.gl/react-google-maps for mapping
  • Recharts for data visualization
  • Playwright for E2E testing

Components:

  • App.tsx - Main application container with hospital data loading
  • Map.tsx - Google Maps integration with hospital markers
  • SimulationViewer.tsx - Simulation playback container
  • PlaybackControls.tsx - Play/pause/speed controls
  • MetricsDashboard.tsx - Real-time metrics display
  • AnimatedAmbulance.tsx - Ambulance marker with status

Custom Hooks:

  • useSimulationPlayer.ts - Manages simulation playback state and animation

State Management:

  • React hooks (useState, useEffect, useCallback)
  • Props drilling for component communication
  • Local state for UI interactions

Backend (FastAPI + Python)

API Endpoints:

GET /api/hospitals
  - Returns list of all Montana hospitals with geocoded locations
  - Cached in data/hospitals_cache.json
  - Response: { hospitals: Hospital[], count: number }

GET /api/config/{simulation_name}
  - Returns simulation configuration
  - Includes ambulance fleet definition
  - Response: { ambulances: Ambulance[], ... }

GET /api/results/{filename}
  - Returns simulation results
  - Includes events and summary statistics
  - Response: { summary: Summary, events: Event[] }

POST /api/simulation/run
  - Runs a new simulation with provided configuration
  - Returns simulation results with events and KPIs

GET /api/simulation/runs
  - Lists all saved simulation runs from database
  - Returns run metadata, status, and summary

GET /api/reports/executive/{run_id}
  - Downloads executive summary PDF report
  - Includes KPI charts and recommendations

GET /api/reports/detailed/{run_id}
  - Downloads detailed analysis PDF report
  - Includes transfer-level data and timing breakdowns

POST /api/reports/comparison
  - Downloads comparison PDF for multiple simulation runs
  - Body: list of run IDs to compare

Data Models:

class Hospital(BaseModel):
    id: str
    name: str
    latitude: float
    longitude: float
    city: str
    type: str
    total_beds: int
    has_emergency: bool
    rating: Optional[float]

class Ambulance(BaseModel):
    id: str
    base_hospital: str
    vehicle_type: str  # 'BLS' | 'ALS' | 'CCT' | 'Air'
    capacity: int
    speed_mph: float   # 45 BLS, 55 ALS, 50 CCT, 150 Air
    range_miles: Optional[float]  # Air ambulances: 175 miles

class Event(BaseModel):
    time: float
    type: str
    ambulance_id: str
    details: dict

CORS Configuration:

  • Allows localhost:5173 for development
  • Configurable for production deployments

Simulation Engine (SimPy)

Core Components:

# Environment
env = simpy.Environment()

# Resources
ambulances = [simpy.Resource(env, capacity=1) for _ in fleet]
hospital_beds = {h.id: simpy.Container(env, capacity=h.beds, init=h.beds) for h in hospitals}

# Processes
def patient_generator(env, hospitals, ambulances):
    """Generates patient transfer requests"""
    while True:
        yield env.timeout(random.expovariate(arrival_rate))
        env.process(handle_transfer(env, ...))

def handle_transfer(env, patient, hospitals, ambulances):
    """Manages individual transfer lifecycle"""
    # 1. Request ambulance
    # 2. Travel to origin
    # 3. Load patient
    # 4. Travel to destination
    # 5. Unload patient
    # 6. Release ambulance

Event Collection:

  • All state changes logged with timestamps
  • Events stored in list for post-processing
  • Summary statistics calculated after simulation

Data Pipeline

Hospital Data Collection:

  1. Download from CMS Hospital Compare dataset
  2. Filter for Montana hospitals
  3. Geocode addresses using Google Maps API
  4. Cache results in JSON format
  5. Validate data quality

Caching Strategy:

  • Hospital data cached for 30 days
  • Simulation results stored permanently
  • Configuration files version controlled

Data Flow

Loading Hospital Data

User → Frontend → Backend → Cache Check → CMS API → Geocoding → Cache → Response

Running Simulation

User Config → SimPy Engine → Event Generation → Results JSON → Backend → Frontend Playback

Playback Animation

Simulation Results → useSimulationPlayer Hook → State Updates → Component Re-renders → Animated Map

Deployment Architecture

Development

Terminal 1: cd web/backend && poetry run uvicorn api:app --reload
Terminal 2: cd web/frontend && npm run dev

Production

Docker Compose:
  - Nginx reverse proxy
  - FastAPI backend (Gunicorn + Uvicorn workers)
  - React frontend (static build)
  - PostgreSQL database with asyncpg
  - OSRM routing server (Montana road network)

Technology Choices Rationale

Why SimPy?

  • Pure Python discrete-event simulation
  • Excellent for queueing systems
  • Well-documented with healthcare examples
  • Easy integration with Python ecosystem

Why FastAPI?

  • Fast, modern Python web framework
  • Automatic API documentation (OpenAPI/Swagger)
  • Type hints and validation with Pydantic
  • Async support for scalability

Why React + TypeScript?

  • Component-based architecture
  • Strong typing prevents bugs
  • Large ecosystem of libraries
  • Excellent developer experience

Why Tailwind CSS?

  • Utility-first approach
  • Consistent design system
  • Minimal CSS bundle size
  • Easy customization

Why @vis.gl/react-google-maps?

  • Official Google Maps integration
  • React-friendly API
  • Advanced features (deck.gl integration)
  • Better than previous react-google-maps library

Performance Considerations

Frontend:

  • Marker clustering for dense hospital networks
  • Virtualized scrolling for event feeds
  • WebSocket updates instead of polling (planned)
  • Lazy loading of simulation data

Backend:

  • Response caching with TTL
  • Async request handling
  • Efficient JSON serialization
  • Connection pooling (future with PostgreSQL)

Simulation:

  • Efficient event queue (heapq in SimPy)
  • Minimal state tracking
  • Batch result processing
  • Configurable time step granularity

Security Considerations

API Security:

  • CORS whitelisting
  • Input validation with Pydantic
  • No sensitive data in responses
  • Rate limiting (future)

Data Privacy:

  • Synthetic patient data only
  • No PHI in current implementation
  • Geographic data publicly available
  • Simulation results anonymized

Testing Strategy

Frontend:

  • E2E tests with Playwright
  • Component tests (planned)
  • Visual regression tests

Backend:

  • Unit tests with pytest
  • API integration tests
  • Data validation tests

Simulation:

  • Unit tests for core logic
  • Validation against analytical models
  • Sensitivity analysis

Implemented Enhancements

Completed Architecture Features:

  1. Database Integration ✅

    • PostgreSQL for persistent storage with asyncpg
    • Event sourcing for simulation history
    • Materialized views for analytics (mv_simulation_kpis, mv_hospital_utilization)
    • Alembic migrations for schema versioning
  2. Weather Integration ✅

    • NOAA API client for real-time weather data
    • Travel time multipliers (wet 1.15x, snow 1.5x, ice 2.0x)
    • Air transport restrictions (icing, visibility, wind)
  3. Advanced Analytics ✅

    • Time-series demand forecasting (SMA, ETS, ARIMA)
    • Statistical comparison with K-S tests
    • Multi-objective policy optimization
    • PDF report generation (WeasyPrint + Jinja2)
  4. Multiple Resource Types ✅

    • BLS/ALS/CCT ground ambulances
    • Air ambulances with operational radius
    • Capability-based dispatch algorithms

Future Enhancements

Planned Architecture Changes:

  1. Real-time Collaboration

    • WebSocket for live simulation streaming
    • Multi-user simulation runs
    • Shared scenarios
  2. Advanced ML Models

    • LSTM for complex seasonal patterns
    • Anomaly detection for demand spikes
    • Automated parameter calibration
  3. Microservices (for scale)

    • Separate simulation engine service
    • Dedicated data ingestion service
    • Independent scaling

Dependencies

Backend:

fastapi>=0.104.0
uvicorn[standard]>=0.24.0
pydantic>=2.4.0
pandas>=2.1.0
simpy>=4.0.0
python-dotenv>=1.0.0
httpx>=0.25.0
sqlalchemy[asyncio]>=2.0.0
asyncpg>=0.29.0
alembic>=1.13.0
weasyprint>=61.0        # PDF generation
jinja2>=3.1.0           # Template rendering
matplotlib>=3.8.0       # Chart generation

Frontend:

react@18.3.1
typescript@5.6.2
@vis.gl/react-google-maps@1.7.1
tailwindcss@3.4.18
@playwright/test@1.49.1
vite@6.0.5
recharts@2.15.0         # Data visualization
react-resizable-panels  # Resizable layout

Configuration

Environment Variables:

  • GOOGLE_MAPS_API_KEY - For geocoding and mapping
  • VITE_GOOGLE_MAPS_API_KEY - Frontend map rendering
  • API_BASE_URL - Backend API endpoint (production)

Configuration Files:

  • tailwind.config.js - Tailwind theme customization
  • vite.config.ts - Vite build configuration
  • playwright.config.ts - E2E test configuration
  • pyproject.toml - Python dependencies

Monitoring and Observability (Future)

  • Application metrics (Prometheus)
  • Error tracking (Sentry)
  • Performance monitoring (APM)
  • Log aggregation (ELK stack)