feat: Implement digestive, urinary, and other major organ systems
This commit significantly expands the patient simulation by adding models for the full digestive and urinary systems, as well as the spleen and spinal cord. This builds on the polymorphic organ framework by adding 9 new organ classes: - Kidneys - Bladder - Stomach - Intestines - Gallbladder - Pancreas - Esophagus - Spleen - SpinalCord Each new organ has its own header, a source file with simplified simulation logic for its unique physiological properties, and is integrated into the main patient model and simulation loop. The build system and example application have been updated to include and demonstrate this new, more comprehensive set of organs.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#include "MedicalLib/Bladder.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
Bladder::Bladder(int id) : Organ(id, "Bladder"), currentVolume(50.0), capacity(500.0) {}
|
||||
|
||||
void Bladder::update(double deltaTime_s) {
|
||||
// In a more complex model, this would be driven by kidney output.
|
||||
// For now, simulate a constant fill rate.
|
||||
const double fillRate_ml_per_s = 0.02;
|
||||
currentVolume += fillRate_ml_per_s * deltaTime_s;
|
||||
currentVolume = std::clamp(currentVolume, 0.0, capacity);
|
||||
}
|
||||
|
||||
void Bladder::addUrine(double amount_ml) {
|
||||
currentVolume += amount_ml;
|
||||
currentVolume = std::clamp(currentVolume, 0.0, capacity);
|
||||
}
|
||||
|
||||
std::string Bladder::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Volume: " << currentVolume << " / " << capacity << " ml";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Bladder::getCurrentVolume() const { return currentVolume; }
|
||||
double Bladder::getCapacity() const { return capacity; }
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Brain.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Brain::Brain(int id) : Organ(id, "Brain"), consciousnessLevel(1.0), cerebralBloodFlow(50.0) {}
|
||||
|
||||
void Brain::update(double deltaTime_s) {
|
||||
const double baseline_consciousness = 1.0;
|
||||
const double baseline_cbf = 50.0;
|
||||
const double theta = 0.05; // Slower reversion for brain metrics
|
||||
const double consciousness_stddev = 0.001;
|
||||
const double cbf_stddev = 0.5;
|
||||
|
||||
consciousnessLevel += theta * (baseline_consciousness - consciousnessLevel) * deltaTime_s + getFluctuation(consciousness_stddev * deltaTime_s);
|
||||
cerebralBloodFlow += theta * (baseline_cbf - cerebralBloodFlow) * deltaTime_s + getFluctuation(cbf_stddev * deltaTime_s);
|
||||
|
||||
consciousnessLevel = std::clamp(consciousnessLevel, 0.0, 1.0);
|
||||
cerebralBloodFlow = std::clamp(cerebralBloodFlow, 40.0, 60.0);
|
||||
}
|
||||
|
||||
std::string Brain::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Consciousness Level: " << consciousnessLevel * 100 << "%\n"
|
||||
<< " Cerebral Blood Flow: " << cerebralBloodFlow << " ml/100g/min";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Brain::getConsciousnessLevel() const { return consciousnessLevel; }
|
||||
double Brain::getCerebralBloodFlow() const { return cerebralBloodFlow; }
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "MedicalLib/Esophagus.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
Esophagus::Esophagus(int id) : Organ(id, "Esophagus"), motility(1.0) {}
|
||||
|
||||
void Esophagus::update(double deltaTime_s) {
|
||||
// Placeholder, no real logic yet.
|
||||
// Fluctuate motility slightly.
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, 0.001);
|
||||
|
||||
motility += d(gen) * deltaTime_s;
|
||||
motility = std::clamp(motility, 0.95, 1.05);
|
||||
}
|
||||
|
||||
std::string Esophagus::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Motility: " << motility * 100 << "%";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Esophagus::getMotility() const { return motility; }
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "MedicalLib/Gallbladder.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
Gallbladder::Gallbladder(int id) : Organ(id, "Gallbladder"), bileStored(30.0) {}
|
||||
|
||||
void Gallbladder::update(double deltaTime_s) {
|
||||
// A real model would be affected by liver production and digestion.
|
||||
// For now, it just sits there with a small fluctuation.
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, 0.01);
|
||||
|
||||
bileStored += d(gen) * deltaTime_s;
|
||||
bileStored = std::clamp(bileStored, 10.0, 50.0);
|
||||
}
|
||||
|
||||
std::string Gallbladder::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Bile Stored: " << bileStored << " ml";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Gallbladder::getBileStored() const { return bileStored; }
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "MedicalLib/Heart.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Heart::Heart(int id) : Organ(id, "Heart"), heartRate(75.0), bloodPressureSystolic(120.0), bloodPressureDiastolic(80.0) {}
|
||||
|
||||
void Heart::update(double deltaTime_s) {
|
||||
const double baseline_hr = 75.0;
|
||||
const double baseline_bp_systolic = 120.0;
|
||||
const double baseline_bp_diastolic = 80.0;
|
||||
const double theta = 0.1; // Mean reversion speed
|
||||
const double hr_stddev = 0.1;
|
||||
const double bp_stddev = 0.1;
|
||||
|
||||
heartRate += theta * (baseline_hr - heartRate) * deltaTime_s + getFluctuation(hr_stddev * deltaTime_s);
|
||||
bloodPressureSystolic += theta * (baseline_bp_systolic - bloodPressureSystolic) * deltaTime_s + getFluctuation(bp_stddev * deltaTime_s);
|
||||
bloodPressureDiastolic += theta * (baseline_bp_diastolic - bloodPressureDiastolic) * deltaTime_s + getFluctuation(bp_stddev * deltaTime_s);
|
||||
|
||||
heartRate = std::clamp(heartRate, 60.0, 100.0);
|
||||
bloodPressureSystolic = std::clamp(bloodPressureSystolic, 90.0, 120.0);
|
||||
bloodPressureDiastolic = std::clamp(bloodPressureDiastolic, 60.0, 80.0);
|
||||
}
|
||||
|
||||
std::string Heart::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Heart Rate: " << heartRate << " bpm\n"
|
||||
<< " Blood Pressure: " << bloodPressureSystolic << "/" << bloodPressureDiastolic << " mmHg";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Heart::getHeartRate() const { return heartRate; }
|
||||
double Heart::getBloodPressureSystolic() const { return bloodPressureSystolic; }
|
||||
double Heart::getBloodPressureDiastolic() const { return bloodPressureDiastolic; }
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Intestines.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Intestines::Intestines(int id) : Organ(id, "Intestines"), nutrientAbsorptionRate(1.0), waterAbsorptionRate(0.1) {}
|
||||
|
||||
void Intestines::update(double deltaTime_s) {
|
||||
const double baseline_nutrient_abs = 1.0;
|
||||
const double baseline_water_abs = 0.1;
|
||||
const double theta = 0.05;
|
||||
const double nutrient_abs_stddev = 0.02;
|
||||
const double water_abs_stddev = 0.005;
|
||||
|
||||
nutrientAbsorptionRate += theta * (baseline_nutrient_abs - nutrientAbsorptionRate) * deltaTime_s + getFluctuation(nutrient_abs_stddev * deltaTime_s);
|
||||
waterAbsorptionRate += theta * (baseline_water_abs - waterAbsorptionRate) * deltaTime_s + getFluctuation(water_abs_stddev * deltaTime_s);
|
||||
|
||||
nutrientAbsorptionRate = std::clamp(nutrientAbsorptionRate, 0.8, 1.2);
|
||||
waterAbsorptionRate = std::clamp(waterAbsorptionRate, 0.08, 0.12);
|
||||
}
|
||||
|
||||
std::string Intestines::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Nutrient Absorption: " << nutrientAbsorptionRate << "\n"
|
||||
<< " Water Absorption: " << waterAbsorptionRate << " ml/s";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Intestines::getNutrientAbsorptionRate() const { return nutrientAbsorptionRate; }
|
||||
double Intestines::getWaterAbsorptionRate() const { return waterAbsorptionRate; }
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Kidneys.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Kidneys::Kidneys(int id) : Organ(id, "Kidneys"), filtrationRate(125.0), urineProductionRate(0.02) {}
|
||||
|
||||
void Kidneys::update(double deltaTime_s) {
|
||||
const double baseline_filtration = 125.0;
|
||||
const double baseline_urine_prod = 0.02;
|
||||
const double theta = 0.03;
|
||||
const double filtration_stddev = 1.0;
|
||||
const double urine_prod_stddev = 0.001;
|
||||
|
||||
filtrationRate += theta * (baseline_filtration - filtrationRate) * deltaTime_s + getFluctuation(filtration_stddev * deltaTime_s);
|
||||
urineProductionRate += theta * (baseline_urine_prod - urineProductionRate) * deltaTime_s + getFluctuation(urine_prod_stddev * deltaTime_s);
|
||||
|
||||
filtrationRate = std::clamp(filtrationRate, 100.0, 150.0);
|
||||
urineProductionRate = std::clamp(urineProductionRate, 0.01, 0.03);
|
||||
}
|
||||
|
||||
std::string Kidneys::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Filtration Rate: " << filtrationRate << " ml/min\n"
|
||||
<< " Urine Production: " << urineProductionRate << " ml/s";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Kidneys::getFiltrationRate() const { return filtrationRate; }
|
||||
double Kidneys::getUrineProductionRate() const { return urineProductionRate; }
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "MedicalLib/Liver.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
// Healthy baseline rates converted to per-second
|
||||
// Bile: 400-800 ml/day -> ~0.0069 ml/s
|
||||
// Glucose: ~90 g/day -> ~0.001 g/s
|
||||
Liver::Liver(int id) : Organ(id, "Liver"), bileProductionRate(0.0069), glucoseProductionRate(0.001) {}
|
||||
|
||||
void Liver::update(double deltaTime_s) {
|
||||
const double baseline_bile_rate = 0.0069;
|
||||
const double baseline_glucose_rate = 0.001;
|
||||
const double theta = 0.02; // Slow reversion for metabolic rates
|
||||
const double bile_stddev = 0.0001;
|
||||
const double glucose_stddev = 0.00005;
|
||||
|
||||
bileProductionRate += theta * (baseline_bile_rate - bileProductionRate) * deltaTime_s + getFluctuation(bile_stddev * deltaTime_s);
|
||||
glucoseProductionRate += theta * (baseline_glucose_rate - glucoseProductionRate) * deltaTime_s + getFluctuation(glucose_stddev * deltaTime_s);
|
||||
|
||||
bileProductionRate = std::clamp(bileProductionRate, 0.005, 0.009);
|
||||
glucoseProductionRate = std::clamp(glucoseProductionRate, 0.0008, 0.0012);
|
||||
}
|
||||
|
||||
std::string Liver::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Bile Production Rate: " << bileProductionRate * 60 << " ml/min\n"
|
||||
<< " Glucose Production Rate: " << glucoseProductionRate * 60 << " g/min";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Liver::getBileProductionRate() const { return bileProductionRate; }
|
||||
double Liver::getGlucoseProductionRate() const { return glucoseProductionRate; }
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Lungs.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Lungs::Lungs(int id) : Organ(id, "Lungs"), respirationRate(16.0), oxygenSaturation(98.0) {}
|
||||
|
||||
void Lungs::update(double deltaTime_s) {
|
||||
const double baseline_rr = 16.0;
|
||||
const double baseline_spo2 = 98.0;
|
||||
const double theta = 0.1; // Mean reversion speed
|
||||
const double rr_stddev = 0.05;
|
||||
const double spo2_stddev = 0.02;
|
||||
|
||||
respirationRate += theta * (baseline_rr - respirationRate) * deltaTime_s + getFluctuation(rr_stddev * deltaTime_s);
|
||||
oxygenSaturation += theta * (baseline_spo2 - oxygenSaturation) * deltaTime_s + getFluctuation(spo2_stddev * deltaTime_s);
|
||||
|
||||
respirationRate = std::clamp(respirationRate, 12.0, 20.0);
|
||||
oxygenSaturation = std::clamp(oxygenSaturation, 96.0, 100.0);
|
||||
}
|
||||
|
||||
std::string Lungs::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Respiration Rate: " << respirationRate << " breaths/min\n"
|
||||
<< " Oxygen Saturation: " << oxygenSaturation << " %";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Lungs::getRespirationRate() const { return respirationRate; }
|
||||
double Lungs::getOxygenSaturation() const { return oxygenSaturation; }
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "MedicalLib/Organ.h"
|
||||
|
||||
Organ::Organ(int id, const std::string& type) : organId(id), organType(type) {}
|
||||
|
||||
int Organ::getId() const {
|
||||
return organId;
|
||||
}
|
||||
|
||||
const std::string& Organ::getType() const {
|
||||
return organType;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Pancreas.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Pancreas::Pancreas(int id) : Organ(id, "Pancreas"), insulinProduction(1.0), glucagonProduction(50.0) {}
|
||||
|
||||
void Pancreas::update(double deltaTime_s) {
|
||||
const double baseline_insulin = 1.0;
|
||||
const double baseline_glucagon = 50.0;
|
||||
const double theta = 0.05;
|
||||
const double insulin_stddev = 0.01;
|
||||
const double glucagon_stddev = 1.0;
|
||||
|
||||
insulinProduction += theta * (baseline_insulin - insulinProduction) * deltaTime_s + getFluctuation(insulin_stddev * deltaTime_s);
|
||||
glucagonProduction += theta * (baseline_glucagon - glucagonProduction) * deltaTime_s + getFluctuation(glucagon_stddev * deltaTime_s);
|
||||
|
||||
insulinProduction = std::clamp(insulinProduction, 0.5, 2.0);
|
||||
glucagonProduction = std::clamp(glucagonProduction, 40.0, 60.0);
|
||||
}
|
||||
|
||||
std::string Pancreas::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Insulin Production: " << insulinProduction << " units/hr\n"
|
||||
<< " Glucagon Production: " << glucagonProduction << " ng/hr";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Pancreas::getInsulinProduction() const { return insulinProduction; }
|
||||
double Pancreas::getGlucagonProduction() const { return glucagonProduction; }
|
||||
+36
-56
@@ -1,74 +1,54 @@
|
||||
#include "MedicalLib/Patient.h"
|
||||
#include <random>
|
||||
#include <algorithm> // For std::clamp
|
||||
#include "MedicalLib/Heart.h"
|
||||
#include "MedicalLib/Lungs.h"
|
||||
#include "MedicalLib/Brain.h"
|
||||
#include "MedicalLib/Liver.h"
|
||||
#include "MedicalLib/Kidneys.h"
|
||||
#include "MedicalLib/Bladder.h"
|
||||
#include "MedicalLib/Stomach.h"
|
||||
#include "MedicalLib/Intestines.h"
|
||||
#include "MedicalLib/Gallbladder.h"
|
||||
#include "MedicalLib/Pancreas.h"
|
||||
#include "MedicalLib/Esophagus.h"
|
||||
#include "MedicalLib/Spleen.h"
|
||||
#include "MedicalLib/SpinalCord.h"
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief Helper function to generate random fluctuations from a normal distribution.
|
||||
* @param stddev The standard deviation of the distribution.
|
||||
* @return A random value.
|
||||
*/
|
||||
double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a new patient with baseline vital signs.
|
||||
* @brief Initializes a new patient with baseline vital signs and a standard set of organs.
|
||||
* @param patientId The ID for the new patient.
|
||||
* @return A Patient struct with default healthy values.
|
||||
*/
|
||||
Patient initializePatient(int patientId) {
|
||||
Patient patient;
|
||||
patient.patientId = patientId;
|
||||
patient.bloodPressureSystolic = 120.0;
|
||||
patient.bloodPressureDiastolic = 80.0;
|
||||
patient.heartRate = 75.0;
|
||||
patient.respirationRate = 16.0;
|
||||
patient.bodyTemperature = 37.0;
|
||||
patient.oxygenSaturation = 98.0;
|
||||
|
||||
// Initialize default organs
|
||||
patient.organs.push_back(std::make_unique<Heart>(1));
|
||||
patient.organs.push_back(std::make_unique<Lungs>(2));
|
||||
patient.organs.push_back(std::make_unique<Brain>(3));
|
||||
patient.organs.push_back(std::make_unique<Liver>(4));
|
||||
patient.organs.push_back(std::make_unique<Kidneys>(5));
|
||||
patient.organs.push_back(std::make_unique<Bladder>(6));
|
||||
patient.organs.push_back(std::make_unique<Stomach>(7));
|
||||
patient.organs.push_back(std::make_unique<Intestines>(8));
|
||||
patient.organs.push_back(std::make_unique<Gallbladder>(9));
|
||||
patient.organs.push_back(std::make_unique<Pancreas>(10));
|
||||
patient.organs.push_back(std::make_unique<Esophagus>(11));
|
||||
patient.organs.push_back(std::make_unique<Spleen>(12));
|
||||
patient.organs.push_back(std::make_unique<SpinalCord>(13));
|
||||
|
||||
return patient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the patient's vital signs based on the time elapsed.
|
||||
* This function simulates minor, random fluctuations around a healthy baseline.
|
||||
* @brief Updates the patient's state by updating the state of all their organs.
|
||||
* @param patient The patient to update.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void updatePatient(Patient& patient, double deltaTime_s) {
|
||||
// Baseline healthy values
|
||||
const double baseline_hr = 75.0;
|
||||
const double baseline_bp_systolic = 120.0;
|
||||
const double baseline_bp_diastolic = 80.0;
|
||||
const double baseline_rr = 16.0;
|
||||
const double baseline_temp = 37.0;
|
||||
const double baseline_spo2 = 98.0;
|
||||
|
||||
// Reversion speed (how quickly vitals return to baseline)
|
||||
const double theta = 0.1;
|
||||
|
||||
// Standard deviations for random fluctuations per second
|
||||
const double hr_stddev = 0.1;
|
||||
const double bp_stddev = 0.1;
|
||||
const double rr_stddev = 0.05;
|
||||
const double temp_stddev = 0.01;
|
||||
const double spo2_stddev = 0.02;
|
||||
|
||||
// Update vitals using a mean-reverting model
|
||||
patient.heartRate += theta * (baseline_hr - patient.heartRate) * deltaTime_s + getFluctuation(hr_stddev * deltaTime_s);
|
||||
patient.bloodPressureSystolic += theta * (baseline_bp_systolic - patient.bloodPressureSystolic) * deltaTime_s + getFluctuation(bp_stddev * deltaTime_s);
|
||||
patient.bloodPressureDiastolic += theta * (baseline_bp_diastolic - patient.bloodPressureDiastolic) * deltaTime_s + getFluctuation(bp_stddev * deltaTime_s);
|
||||
patient.respirationRate += theta * (baseline_rr - patient.respirationRate) * deltaTime_s + getFluctuation(rr_stddev * deltaTime_s);
|
||||
patient.bodyTemperature += theta * (baseline_temp - patient.bodyTemperature) * deltaTime_s + getFluctuation(temp_stddev * deltaTime_s);
|
||||
patient.oxygenSaturation += theta * (baseline_spo2 - patient.oxygenSaturation) * deltaTime_s + getFluctuation(spo2_stddev * deltaTime_s);
|
||||
|
||||
// Clamp values to within healthy physiological ranges
|
||||
patient.heartRate = std::clamp(patient.heartRate, 60.0, 100.0);
|
||||
patient.bloodPressureSystolic = std::clamp(patient.bloodPressureSystolic, 90.0, 120.0);
|
||||
patient.bloodPressureDiastolic = std::clamp(patient.bloodPressureDiastolic, 60.0, 80.0);
|
||||
patient.respirationRate = std::clamp(patient.respirationRate, 12.0, 20.0);
|
||||
patient.bodyTemperature = std::clamp(patient.bodyTemperature, 36.5, 37.3);
|
||||
patient.oxygenSaturation = std::clamp(patient.oxygenSaturation, 96.0, 100.0);
|
||||
// Update all organs
|
||||
for (auto& organ : patient.organs) {
|
||||
organ->update(deltaTime_s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "MedicalLib/SpinalCord.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
SpinalCord::SpinalCord(int id) : Organ(id, "SpinalCord"), signalConductionVelocity(70.0) {}
|
||||
|
||||
void SpinalCord::update(double deltaTime_s) {
|
||||
const double baseline_velocity = 70.0;
|
||||
const double theta = 0.01;
|
||||
const double velocity_stddev = 0.1;
|
||||
|
||||
signalConductionVelocity += theta * (baseline_velocity - signalConductionVelocity) * deltaTime_s + getFluctuation(velocity_stddev * deltaTime_s);
|
||||
|
||||
signalConductionVelocity = std::clamp(signalConductionVelocity, 60.0, 80.0);
|
||||
}
|
||||
|
||||
std::string SpinalCord::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Signal Velocity: " << signalConductionVelocity << " m/s";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double SpinalCord::getSignalConductionVelocity() const { return signalConductionVelocity; }
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "MedicalLib/Spleen.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Spleen::Spleen(int id) : Organ(id, "Spleen"), redBloodCellCount(4.5), whiteBloodCellCount(7.5) {}
|
||||
|
||||
void Spleen::update(double deltaTime_s) {
|
||||
const double baseline_rbc = 4.5;
|
||||
const double baseline_wbc = 7.5;
|
||||
const double theta = 0.02;
|
||||
const double rbc_stddev = 0.01;
|
||||
const double wbc_stddev = 0.05;
|
||||
|
||||
redBloodCellCount += theta * (baseline_rbc - redBloodCellCount) * deltaTime_s + getFluctuation(rbc_stddev * deltaTime_s);
|
||||
whiteBloodCellCount += theta * (baseline_wbc - whiteBloodCellCount) * deltaTime_s + getFluctuation(wbc_stddev * deltaTime_s);
|
||||
|
||||
redBloodCellCount = std::clamp(redBloodCellCount, 4.0, 5.0);
|
||||
whiteBloodCellCount = std::clamp(whiteBloodCellCount, 5.0, 10.0);
|
||||
}
|
||||
|
||||
std::string Spleen::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " RBC Count: " << redBloodCellCount << " million/uL\n"
|
||||
<< " WBC Count: " << whiteBloodCellCount << " thousand/uL";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Spleen::getRedBloodCellCount() const { return redBloodCellCount; }
|
||||
double Spleen::getWhiteBloodCellCount() const { return whiteBloodCellCount; }
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "MedicalLib/Stomach.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, stddev);
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Stomach::Stomach(int id) : Organ(id, "Stomach"), phLevel(2.0), digestionRate(1.0) {}
|
||||
|
||||
void Stomach::update(double deltaTime_s) {
|
||||
// For now, these values just fluctuate around a baseline.
|
||||
const double baseline_ph = 2.0;
|
||||
const double baseline_digestion = 1.0;
|
||||
const double theta = 0.1;
|
||||
const double ph_stddev = 0.05;
|
||||
const double digestion_stddev = 0.02;
|
||||
|
||||
phLevel += theta * (baseline_ph - phLevel) * deltaTime_s + getFluctuation(ph_stddev * deltaTime_s);
|
||||
digestionRate += theta * (baseline_digestion - digestionRate) * deltaTime_s + getFluctuation(digestion_stddev * deltaTime_s);
|
||||
|
||||
phLevel = std::clamp(phLevel, 1.5, 3.5);
|
||||
digestionRate = std::clamp(digestionRate, 0.5, 1.5);
|
||||
}
|
||||
|
||||
std::string Stomach::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " pH Level: " << phLevel << "\n"
|
||||
<< " Digestion Rate: " << digestionRate;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Stomach::getPhLevel() const { return phLevel; }
|
||||
double Stomach::getDigestionRate() const { return digestionRate; }
|
||||
Reference in New Issue
Block a user