Commit 832898cc authored by fmg005's avatar fmg005

Modified algorithm implementation

parent 432d0fbc
builds/
cmdsim_old.cmake
......@@ -49,8 +49,8 @@ class Controller {
PhysiologyData* m_data;
std::map<string, Pump*> m_pumps;
double WAIT_10;
double WAIT_5;
double WAIT_10_MIN;
double WAIT_5_MIN;
unsigned long initialize_time_index;
unsigned long checkmap_time_index;
unsigned long ensure_map_time_index;
......@@ -77,19 +77,36 @@ class Controller {
bool STAY_IN_4;
bool ELSE_STAY_IN_4;
double currentNorepiRate;
;
//Algorithm stuff
double currentMAP;
double currentNorepiInfusionRate;
double SalineInfusionRate;
double maxNorepinephrineInfusionRate;
double percentOfRate;
double targetMAPRangeMax;
double targetMAPRangeMin;
double MAPIncreaseThreshold;
unsigned long nextUpdateTime;
/* Pointer to current function to run for algorithm */
void (Controller::*respondToData)(void);
/* Initialize in "Simulation Plan" */
void initializeInfusions(void);
/* Wait for MAP increase in "Simulation Plan" */
void waitForMAPIncrease(void);
/* Ensure MAP decline after increase in "Simulation Plan" */
void ensureMAPDeclineAfterIncrease(void);
/* Maintain MAP in range in "Simulation Plan" */
void maintainMAPInRange(void);
double MAP;
//function variable for functions to set pump rates
//void pumpSetRate; // assuming dictionary
public:
......
......@@ -20,6 +20,8 @@ namespace CMD {
double simulation_injury_start;
double simulation_injury_stop;
double sim_currentTime;
unsigned long simulation_injury_start_timestep;
unsigned long simulation_injury_stop_timestep;
......
......@@ -54,6 +54,9 @@ class Pump : public MedicalDevice {
SESubstanceCompoundInfusion* m_infusion;
SESubstanceInfusion* bpdrug_infusion;
double NorepiConcentration;
double SalineBagVolume;
public:
......
......@@ -31,7 +31,7 @@ class SimulationLogger {
void LogData(double, string, string, string, PhysiologyData&);
void LogRate(double, string, string, string, int);
void LogRate(double, string, string, string, double);
//Destructor
~SimulationLogger();
......
This diff is collapsed.
......@@ -10,8 +10,10 @@ Pump::Pump()
//Overload Constructor
Pump::Pump(CMD::Environment* env, PhysiologyData* data, string substance): m_env(env), m_data(data),
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0,0ul)} {
//pump_data = {make_pair(0,0ul)};
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0.0,0ul)} {
NorepiConcentration = 32;
SalineBagVolume = 500;
}
......@@ -114,14 +116,14 @@ void Pump::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* fil
SESubstanceCompound* saline = engine->GetSubstanceManager().GetCompound(m_substance);
m_infusion = new SESubstanceCompoundInfusion(*saline);
//the total volume in the bag of Saline
m_infusion->GetBagVolume().SetValue(500,VolumeUnit::mL);
m_infusion->GetBagVolume().SetValue(SalineBagVolume, VolumeUnit::mL);
}
if(m_substance == "Norepinephrine") {
SESubstance* bpdrug = engine->GetSubstanceManager().GetSubstance(m_substance);
bpdrug_infusion = new SESubstanceInfusion(*bpdrug);
bpdrug_infusion->GetConcentration().SetValue(16, MassPerVolumeUnit::ug_Per_mL);
bpdrug_infusion->GetConcentration().SetValue(NorepiConcentration, MassPerVolumeUnit::ug_Per_mL);
}
}
......
......@@ -128,7 +128,8 @@ void Simulation(const string patient_name)
//instatiate Hemorrhage Action
SEHemorrhage hemorrhageLeg;
double MAP;
const double initialMAP = 70.0;
double currentMAP;
// Configuration file path
// Note: Path is relative to the bin folder not src folder
......@@ -178,6 +179,8 @@ void Simulation(const string patient_name)
// stop when the set time is reached
while (sim_env.time_index <= sim_env.simulation_timesteps) {
sim_env.sim_currentTime = pe->GetSimulationTime(TimeUnit::s);
//cout << "sim time "<< sim_env.sim_currentTime <<endl;
// event_hemorrage_start
if(sim_env.time_index == sim_env.simulation_injury_start_timestep ){
// Hemorrhage Starts - instantiate a hemorrhage action and have the engine process it
......@@ -193,9 +196,9 @@ void Simulation(const string patient_name)
STOP = true;
}
MAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
if( MAP <= 55.0 && STOP){
if( currentMAP <= initialMAP && STOP){
cout << "\nHemorrhage Stoppd at: " << pe->GetSimulationTime(TimeUnit::s) << endl;
......@@ -274,6 +277,8 @@ void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::sha
env->simulation_injury_stop_timestep = env->simulation_injury_stop / env->engine_timestep;
env->vector_index = 0;
env->sim_currentTime = engine->GetSimulationTime(TimeUnit::s);
//env->logger = std::make_shared<SimulationLogger>("SimulatoinEngineLog.txt");
}// End Global_LoadConfig
......
......@@ -29,7 +29,7 @@ void SimulationLogger::LogData(double time, string entity, string event, string
void SimulationLogger::LogRate(double time, string entity, string event, string action, int rate) {
void SimulationLogger::LogRate(double time, string entity, string event, string action, double rate) {
m_out_file << time <<","<< entity <<","<< event <<","<< action <<","<<
......
......@@ -10,13 +10,18 @@ Controller::Controller(): MAX_RATE_Hz(50.0) {
Controller::Controller(CMD::Environment* env, PhysiologyData* data, std::map<string, Pump*>& pumps ) : m_env(env),
m_data(data), m_pumps(pumps), MAX_RATE_Hz(50.0) {
srand(time(0)); // seed values using system time
// Initalize algorithm configuration variables
currentNorepiInfusionRate = 0;
SalineInfusionRate = 75.0;
maxNorepinephrineInfusionRate = 112.5;
targetMAPRangeMax = 80.0;
targetMAPRangeMin = 75.0;
MAPIncreaseThreshold = 85;
percentOfRate = 0;
currentMAP = 0;
// initialise array from which rates will be picked randomly
array_rate[0] = 300;
array_rate[1] = 350;
array_rate[2] = 200;
//array_rate[3] = 50;
/* The first action the controller should take is initialize infusions */
respondToData = &Controller::initializeInfusions;
}
......@@ -24,87 +29,27 @@ Controller::Controller(CMD::Environment* env, PhysiologyData* data, std::map<str
void Controller::update(std::unique_ptr<PhysiologyEngine>& engine) {
// check controller input rate
if (m_env->time_index % input_period == 0) {
// check controller input rate
if (m_env->time_index % input_period == 0) {
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout<<"Controller receives data from Monitor at: "<<engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout<<"Controller receives data from Monitor at: "<<engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
// Gets data from Monitor
GetData();
m_env->logger->LogData(m_env->sim_currentTime,"Controller",
"RECEIVE","Received data from Monitor BP", patient_state.at(m_env->vector_index-1) );
// Gets data from Monitor
GetData();
// Get the current MAP value
currentMAP = patient_state.at(m_env->vector_index-1).pressure;
/* execute the algorithm to respond to the data */
((this)->*respondToData)();
m_env->logger->LogData(
engine->GetSimulationTime(TimeUnit::s),
"Controller",
"RECEIVE",
"Received data from Monitor BP",
patient_state.at(m_env->vector_index-1)
);
/*
// why cant't I compare using patient value
double p = patient_state.at(m_env->vector_index-1).pressure;
double value = (int)(p*100 + .5);
double v = (double)value / 100;
bool x = (p > 95.07);
cout <<x<<endl;
*/
//if ( x) doesn't work if x is not true for first loop
if ( m_env->time_index % 96 == 0 ) {
new_rate = array_rate[rand() % 3];
m_env->logger->LogRate(
engine->GetSimulationTime(TimeUnit::s),
"Controller",
"RATE_CHANGE",
"Controller sends Command to saline Pump",
new_rate
);
cout<< "Command SENT to saline PUMP: "<< engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
//Send information to pump (rate, time index)
//SetRate(new_rate, m_env->time_index);
//cout << "Invoking Change Pump rate command" << endl;
//cout << "new rate " << new_rate << endl;
//cout << "Controller time index " << m_env->time_index << endl;
m_pumps["saline"]->ChangePumpRate(new_rate, m_env->time_index);
/*
cout<< "Command SENT to bpdrug PUMP: "<< engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
m_env->logger->LogRate(
engine->GetSimulationTime(TimeUnit::s),
"Controller",
"RATE_CHANGE",
"Controller sends Command to bpdrug Pump",
new_rate
);
//m_pumps["bpdrug"]->ChangePumpRate(new_rate, m_env->time_index);
//pumpSetRate['saline'](salinerate);
//pumpSetRate['BPdrug'](bprate);
*/
//m_env->pump_index++;
}
} // End check input rate condition
} // End check input rate condition
}; // End Controller update()
......@@ -160,6 +105,12 @@ void Controller::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const cha
time_step = engine->GetTimeStep(TimeUnit::s);
//MAX_RATE_Hz = 1/time_step;
WAIT_10_MIN = cfg.lookup("controller.algorithm.wait_10");
WAIT_5_MIN = cfg.lookup("controller.algorithm.wait_5");
WAIT_10_MIN = (60 * WAIT_10_MIN)/time_step; // 10 min
WAIT_5_MIN = (60 * WAIT_5_MIN)/time_step; // 5 min
// integer input rate for controller
input_period = (1/controller_rate_Hz) / time_step;
//is_input_multiple = fmod(MAX_RATE_Hz, controller_rate_Hz) == 0.0;
......@@ -267,3 +218,110 @@ Controller::~Controller() {
patient_state.clear();
}
//Algorithm functions------------------------
/* Initialize in "Simulation Plan" */
void Controller::initializeInfusions(void){
currentNorepiInfusionRate = maxNorepinephrineInfusionRate;
// log rate
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
// set next update time
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::waitForMAPIncrease;
}
/* Wait for MAP increase in "Simulation Plan" */
void Controller::waitForMAPIncrease(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > MAPIncreaseThreshold) {
currentNorepiInfusionRate = percentOfRate * maxNorepinephrineInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::ensureMAPDeclineAfterIncrease;
}
else {
nextUpdateTime = m_env->time_index + WAIT_5_MIN;
}
}
}
/* Ensure MAP decline after increase in "Simulation Plan" */
void Controller::ensureMAPDeclineAfterIncrease(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > MAPIncreaseThreshold){
currentNorepiInfusionRate = percentOfRate * currentNorepiInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
else {
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::maintainMAPInRange;
}
}
}
/* Maintain MAP in range in "Simulation Plan" */
void Controller::maintainMAPInRange(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > targetMAPRangeMax){
currentNorepiInfusionRate = percentOfRate * currentNorepiInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
else if(currentMAP < targetMAPRangeMin) {
currentNorepiInfusionRate = percentOfRate * maxNorepinephrineInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_5_MIN;
}
else {
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
}
}
......@@ -10,8 +10,10 @@ Pump::Pump()
//Overload Constructor
Pump::Pump(CMD::Environment* env, PhysiologyData* data, string substance): m_env(env), m_data(data),
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0,0ul)} {
//pump_data = {make_pair(0,0ul)};
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0.0,0ul)} {
NorepiConcentration = 32;
SalineBagVolume = 500;
}
......@@ -108,36 +110,56 @@ void Pump::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* fil
}
// instatiate infusion compound
SESubstanceCompound* saline = engine->GetSubstanceManager().GetCompound(m_substance);
m_infusion = new SESubstanceCompoundInfusion(*saline);
// Set up substance infusion
if(m_substance == "Saline") {
// instatiate infusion compound
SESubstanceCompound* saline = engine->GetSubstanceManager().GetCompound(m_substance);
m_infusion = new SESubstanceCompoundInfusion(*saline);
//the total volume in the bag of Saline
m_infusion->GetBagVolume().SetValue(SalineBagVolume, VolumeUnit::mL);
}
//the total volume in the bag of Saline
m_infusion->GetBagVolume().SetValue(500,VolumeUnit::mL);
if(m_substance == "Norepinephrine") {
SESubstance* bpdrug = engine->GetSubstanceManager().GetSubstance(m_substance);
bpdrug_infusion = new SESubstanceInfusion(*bpdrug);
bpdrug_infusion->GetConcentration().SetValue(NorepiConcentration, MassPerVolumeUnit::ug_Per_mL);
}
}
void Pump::SetInfusionRate(std::unique_ptr<PhysiologyEngine>& eng, int infusion_rate) {
void Pump::SetInfusionRate(std::unique_ptr<PhysiologyEngine>& eng, double infusion_rate) {
pump_rate = infusion_rate;
//The rate to admnister the compound in the bag in this case saline
m_infusion->GetRate().SetValue(pump_rate, VolumePerTimeUnit::mL_Per_hr);
eng->ProcessAction(*m_infusion);
// Can't get curent BAG volume : returns the inital set volume ie 500
//cout << "CURRENT BAG Volume" << m_infusion->GetBagVolume().GetValue(VolumeUnit::mL)<< endl;
if(m_substance == "Saline") {
//The rate to admnister the compound in the bag in this case saline
m_infusion->GetRate().SetValue(pump_rate, VolumePerTimeUnit::mL_Per_hr);
eng->ProcessAction(*m_infusion);
cout<< m_substance+"_Pump rate changed to: " << pump_rate <<endl;
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
}
if(m_substance == "Norepinephrine") {
bpdrug_infusion->GetRate().SetValue(pump_rate, VolumePerTimeUnit::mL_Per_hr);
eng->ProcessAction(*bpdrug_infusion);
cout<< m_substance+"_Pump rate changed to: " << pump_rate <<endl;
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout<< m_substance+"_Pump rate changed to: " << pump_rate <<endl;
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
}
}
void Pump::ChangePumpRate(int new_rate, unsigned long new_time_index){
void Pump::ChangePumpRate(double new_rate, unsigned long new_time_index){
pump_data.push_back(make_pair(new_rate, new_time_index));
//SetInfusionRate(new_rate, new_time_index);
......@@ -156,11 +178,25 @@ void Pump::Stop() {
//Nolonger static variable
//vector< pair<int, unsigned long> > Pump::pump_data;
void Pump::Clear() {
m_infusion = nullptr;
bpdrug_infusion = nullptr;
// clear data accumulated in te containr after simulation
pump_data.clear();
}
// Destructor
Pump::~Pump() {
// clear data accumulated in te containr after simulation
pump_data.clear();
delete m_infusion;
};
Pump::Clear();
if (m_infusion == nullptr){
delete m_infusion;
}
if (bpdrug_infusion == nullptr) {
delete bpdrug_infusion;
}
}
......@@ -16,6 +16,7 @@
// Include the various types you will be using in your code
#include "scenario/SEDataRequestManager.h"
#include "patient/actions/SEHemorrhage.h"
#include "patient/actions/SESubstanceCompoundInfusion.h"
#include "system/physiology/SEBloodChemistrySystem.h"
......@@ -59,8 +60,8 @@ int main(){
patients_list = get_global_patients("./config/simulation_scenario.cfg", cf);
/*
/*
for(auto patient: patients_list) {
// start timer
t1 = clock();
......@@ -79,7 +80,8 @@ int main(){
cout << " took "<< sim_time_secs <<" seconds ";
cout <<"or " << sim_time_mins <<" minutes"<<endl;
}
*/
*/
t1 = clock();
......@@ -98,8 +100,6 @@ int main(){
}
......@@ -128,7 +128,8 @@ void Simulation(const string patient_name)
//instatiate Hemorrhage Action
SEHemorrhage hemorrhageLeg;
double MAP;
const double initialMAP = 70.0;
double currentMAP;
// Configuration file path
// Note: Path is relative to the bin folder not src folder
......@@ -151,11 +152,11 @@ void Simulation(const string patient_name)
Pump pump_saline(&sim_env, &data, "Saline");
pump_saline.LoadConfig(pe, fname);
//Pump pump_bpdrug(&sim_env, &data, "Saline");
//pump_bpdrug.LoadConfig(pe, fname);
Pump pump_bpdrug(&sim_env, &data, "Norepinephrine");
pump_bpdrug.LoadConfig(pe, fname);
pumps.insert(make_pair("saline", &pump_saline));
//pumps.insert(make_pair("bpdrug", &pump_bpdrug));
pumps.insert(make_pair("bpdrug", &pump_bpdrug));
//Initialize Controller
Controller controller(&sim_env, &data, pumps);
......@@ -178,6 +179,8 @@ void Simulation(const string patient_name)
// stop when the set time is reached
while (sim_env.time_index <= sim_env.simulation_timesteps) {
sim_env.sim_currentTime = pe->GetSimulationTime(TimeUnit::s);
//cout << "sim time "<< sim_env.sim_currentTime <<endl;
// event_hemorrage_start
if(sim_env.time_index == sim_env.simulation_injury_start_timestep ){
// Hemorrhage Starts - instantiate a hemorrhage action and have the engine process it
......@@ -187,15 +190,15 @@ void Simulation(const string patient_name)
//the location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
//the rate of hemorrhage
hemorrhageLeg.GetRate().SetValue(100,VolumePerTimeUnit::mL_Per_min);
hemorrhageLeg.GetRate().SetValue(150,VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
STOP = true;
}
MAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
if( MAP <= 55.0 && STOP){
if( currentMAP <= initialMAP && STOP){
cout << "\nHemorrhage Stoppd at: " << pe->GetSimulationTime(TimeUnit::s) << endl;
......@@ -218,7 +221,7 @@ void Simulation(const string patient_name)
monitor.update(pe);
controller.update(pe);
pumps["saline"]->update(pe);
//pumps["bpdrug"]->update(pe);
pumps["bpdrug"]->update(pe);
}
......@@ -274,6 +277,8 @@ void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::sha
env->simulation_injury_stop_timestep = env->simulation_injury_stop / env->engine_timestep;
env->vector_index = 0;
env->sim_currentTime = engine->GetSimulationTime(TimeUnit::s);
//env->logger = std::make_shared<SimulationLogger>("SimulatoinEngineLog.txt");
}// End Global_LoadConfig
......
......@@ -29,7 +29,7 @@ void SimulationLogger::LogData(double time, string entity, string event, string
void SimulationLogger::LogRate(double time, string entity, string event, string action, int rate) {
void SimulationLogger::LogRate(double time, string entity, string event, string action, double rate) {
m_out_file << time <<","<< entity <<","<< event <<","<< action <<","<<
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment