Skip to content

Theclasspro1/Twinning

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HemaTwin Mission Control

HemaTwin is a Digital Twin pipeline that combines:

  1. Real-time BioGears telemetry (physiology from the engine)
  2. Stochastic hematology analytics (hemolysis, hemoglobin, risk)
  3. A mission dashboard that explains EVA readiness in live terms

This document explains the implementation in code terms, especially Monte Carlo and hemoglobin dynamics.

1) System Components

A) Engine Runtime and Mirroring

  • File: shared_data/engine_listener.py
  • Purpose:
    • start BioGears scenario runs
    • find correct run output CSV
    • continuously mirror output to shared_data/SpaceAnemiaResults.csv
    • expose engine status and twin sync metadata

B) Web API and Orchestration

  • File: web/main.py
  • Purpose:
    • serve dashboard
    • trigger simulation with dynamic scenario generation
    • parse mirrored telemetry safely while file is still growing
    • expose stochastic analytics endpoints

C) Stochastic Analytics Core

  • File: shared_data/stochastic_generator.py
  • Purpose:
    • generate hourly hemolysis and EPO response
    • simulate hemoglobin progression
    • run Monte Carlo risk bands
    • run sensitivity and recovery branches
    • generate risk conclusions

D) Frontend Dashboard

  • File: web/index.html
  • Purpose:
    • gather controls (anemia, exercise, scenario profile)
    • poll telemetry and twin state
    • keep hemoglobin display synchronized with mission progress
    • render readiness, grounding ETA, and reason strings
    • render analytics charts/panels

2) End-to-End Runtime Flow

  1. User clicks INITIATE BIO-SIM.
  2. Frontend calls /trigger_simulation with dynamic=true and current controls.
  3. web/main.py creates a scenario file from slider values.
  4. engine_listener.py launches bg-cli with that scenario.
  5. While bg-cli is running, engine_listener.py mirrors fresh rows to shared_data/SpaceAnemiaResults.csv.
  6. Frontend polls /telemetry and /twin_state on intervals.
  7. Frontend maps current simulation time to current stochastic timeline hour and updates Hb live.
  8. EVA status, grounding estimate, and explanation text refresh continuously.
  9. RUN ANALYTICS calls sensitivity, monte_carlo, recovery, conclusions and updates all analytics panels.

3) Code Walkthrough By File

3.1 web/main.py

Core helper logic

  • _clamp(v, lo, hi)

    • utility to keep numeric inputs in valid bounds.
  • _build_dynamic_scenario(base_scenario, anemia_severity, exercise_intensity)

    • builds a temporary scenario XML in /shared_data.
    • transforms control values into:
      • anemia reduction
      • exercise phase intensities
      • acute stress severity phases
    • anemia reduction is capped for BioGears compatibility.

Simulation control endpoints

  • GET /

    • serves dashboard HTML.
  • GET /trigger_simulation

    • builds dynamic scenario if requested.
    • calls engine /start_engine with resolved scenario filename.
    • returns requested_scenario and resolved_scenario for UI traceability.
  • GET /engine_status

    • proxies engine state (running, done, error, csv path).
  • GET /twin_state

    • proxies twin metadata, including last sync and source/destination CSV path.

Telemetry endpoint

  • GET /telemetry
    • reads mirrored CSV with defensive parsing.
    • strips unit row, converts numeric fields, normalizes SpO2 to percent.
    • returns row_count and parsed records.
    • handles waiting states when file is missing, empty, or mid-write.

Analytics endpoints

  • GET /hemolysis_profile

    • single stochastic timeline run with current controls.
  • GET /monte_carlo

    • percentile bands and grounding risk.
  • GET /sensitivity

    • nominal vs high-stress comparison.
  • GET /recovery

    • intervention branch simulation.
  • GET /conclusions

    • narrative conclusions from Monte Carlo risk outputs.

3.2 shared_data/engine_listener.py

Output CSV selection hardening

  • _is_biogears_telemetry_csv(path)

    • checks for Time, HeartRate, OxygenSaturation columns.
    • prevents accidental use of analytics CSVs as live telemetry.
  • find_output_csv(search_roots, started_at)

    • searches known BioGears output patterns.
    • keeps only files newer than run start.
    • uses telemetry header validation before selecting.

Real-time mirroring

  • mirror_csv_once(csv_path)

    • copies source CSV to shared_data/SpaceAnemiaResults.csv.
    • updates sync timestamp and source path in sim_state.
  • stream_mirror_while_running(process, search_roots, started_at)

    • loops while process is alive, mirrors on mtime change.
    • does final flush pass after process exit.

Engine run orchestration

  • run_biogears_cli(scenario_file)
    • validates scenario exists.
    • starts bg-cli scenario run.
    • mirrors output live.
    • writes final status/error into sim_state.

Service endpoints

  • POST /start_engine

    • starts run in background task.
  • GET /engine_status

    • returns sim_state snapshot.
  • GET /twin_state

    • returns Digital Twin metadata payload.

3.3 shared_data/stochastic_generator.py

This file is the core of Monte Carlo and hemoglobin modeling.

Inputs and profile shaping

  • _resolve_profile(profile_name, anemia_severity, exercise_intensity)
    • starts from nominal or high_stress preset.
    • modifies key parameters using severity/exercise:
      • hemolysis_mean
      • epo_suppression
      • spike frequency and magnitudes

Stochastic process generation

  • _generate_hemolysis_rate(hours, params, rng)

    • hourly hemolysis pressure sampled from lognormal distribution.
  • _inject_events(hr_series, params, hours, rng)

    • injects:
      • acute hemolytic spikes (Poisson-distributed start times)
      • EVA exertion windows at fixed mission times
    • returns event metadata used by UI timeline.
  • _generate_epo_response(hours, hr_series, params, rng)

    • baseline normal noise around suppressed EPO mean.
    • stress-coupled increment from hr_series.

Hemoglobin update equation

At each hour i > 0:

hb_next = hb_prev - rbc_loss + epo_recovery + baseline_recovery (+ restorative_pull when low)

Where:

  • rbc_loss = hr_series[i] * rbc_volume_factor
  • epo_recovery = epo_series[i] * epo_recovery_factor
  • rbc_volume_factor = (65 + 95severity + 45exercise) * depletion_scale
  • epo_recovery_factor = 0.50 - 0.10*severity
  • baseline_recovery = 0.14 + 0.20*(1-severity)

Implementation details:

  • floor and ceiling are applied to keep Hb in physiological bounds.
  • if previous Hb is low, a small restorative pull is added to avoid unrealistic collapse in mild cases.

Readiness and grounding prediction

  • _compute_readiness_status(hb_series, hr_series)

    • labels each hour GREEN/YELLOW/RED using modeled thresholds.
  • _predict_grounding_day(hb_series)

    • if already below grounded threshold, grounding is immediate.
    • otherwise slope of last window is used to estimate days/hours to grounding.

Single-run profile generation

  • simulate_profile(...)
    • executes all steps above for one timeline.
    • returns:
      • timeline list (hourly hb, hr, epo, readiness)
      • events list
      • grounding prediction
      • summary stats

4) Monte Carlo: Exactly How It Works

Function: run_monte_carlo(...)

Algorithm:

  1. Choose number of runs n (minimum safety floor is enforced).
  2. For run index i:
    • call simulate_profile with deterministic seed 1000 + i
    • extract hemoglobin timeline into hb_runs[i, :]
    • mark grounded_by_day2 if any Hb < threshold in first 48 hours
    • mark grounded_by_day3 if any Hb < threshold in first 72 hours
  3. Across hb_runs, compute hourly percentiles:
    • P5, P50, P95
  4. Convert grounding booleans to probabilities:
    • grounding_probability_day2 = mean(grounded_by_day2)
    • grounding_probability_day3 = mean(grounded_by_day3)
  5. Return:
    • bands: hour-wise hb_p5, hb_p50, hb_p95
    • risk: day2/day3 grounding probabilities

Why this is useful:

  • captures uncertainty envelope instead of only one deterministic line.
  • P50 shows expected trajectory, P5 shows low-tail risk trajectory.

5) Sensitivity, Recovery, Conclusions

Sensitivity

  • run_sensitivity_analysis(...)
    • runs Monte Carlo on:
      • Nominal profile with current controls
      • High-Stress profile with stressed offsets
    • returns two median trajectories and risks for side-by-side comparison.

Recovery

  • simulate_recovery(...)
    • simulates three interventions:
      • Rest
      • IronSupplement
      • EPOTherapy
    • each branch updates Hb and HR each hour using branch-specific gains.
    • outputs time_to_green_hours and final state metrics.

Conclusions

  • generate_conclusions(monte_carlo_output)
    • derives mission text from risk and percentile bands.
    • statements are tail-aware, not only median-aware.

6) Frontend Runtime Behavior and Synchronization

6.1 Main control and polling loop

  • updateControlValues and getControlParams manage UI control state.
  • startSimulation does:
    • preloads stochastic profile for current controls
    • triggers dynamic BioGears run
    • starts polling loops:
      • telemetry: 1s
      • engine status: 2s
      • twin state: 1s

6.2 Dynamic hemoglobin synchronization

In updateCharts(rows):

  1. Read latest engine time from telemetry row.
  2. Convert engine progress to stochastic timeline index:
    • hourIdx = floor((simTime / 1260) * maxHour)
  3. Set currentHb from stochasticTimeline[hourIdx].hemoglobin_g_per_L.
  4. Push into hbHistory for trend-based grounding estimation.

This is the key fix that prevents static/preloaded Hb behavior.

6.3 Readiness and grounding explanation

  • computeReadiness(hr, spo2, hb)

    • computes RED/YELLOW/GREEN for mission decision state.
  • updateGroundingAndReason(status, hr, spo2, hb)

    • sets days to grounding using status + Hb trend.
    • writes explicit reasons like:
      • low SpO2
      • elevated HR
      • low Hb
    • if no warning reasons exist, writes green-safe reason.

6.4 Analytics rendering

  • refreshAdvancedAnalytics runs four endpoints in parallel:
    • /sensitivity
    • /monte_carlo
    • /recovery
    • /conclusions
  • renderSensitivity, renderMonteCarlo, renderRecovery, renderConclusions update dedicated panels/charts.

7) Important Implementation Notes

  1. Depletion slider was intentionally removed from frontend controls.
  2. Backend still supports depletion_scale with default behavior for compatibility.
  3. Telemetry CSV selection is hardened to avoid non-BioGears CSV contamination.
  4. Frontend no longer auto-loads profile on page load to avoid misleading pre-run visuals.
  5. Twin-state metadata is surfaced to UI for transparency of sync health.

8) Files Worked On (Current Feature Set)

  • shared_data/engine_listener.py
  • web/main.py
  • shared_data/stochastic_generator.py
  • web/index.html
  • README.md
  • .gitignore

9) Quick Verification Checklist

  1. Start services with docker compose.
  2. Open dashboard at localhost:5000.
  3. Start a simulation.
  4. Confirm telemetry values increment while run is active.
  5. Confirm Hb changes over mission progress (not fixed).
  6. Confirm RED/YELLOW/GREEN reason text updates.
  7. Click RUN ANALYTICS and confirm all four panels refresh.
  8. Confirm Monte Carlo risk text and percentile chart are populated.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors