Commit 19b83884 authored by fmg005's avatar fmg005
Browse files

Fixed bugs in algorithm 2 source files

parent 9a80b2ef
......@@ -54,31 +54,13 @@ void Controller::update(std::unique_ptr<PhysiologyEngine>& engine) {
}; // End Controller update()
void Controller::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* file_path) {
void Controller::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::shared_ptr<Config>& cf) {
try
{
// Read configration file
cfg.readFile(file_path);
}
catch(const FileIOException &fioex)
{
std::cerr << "I/O error while reading file." << std::endl;
}
catch(const ParseException &pex)
{
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
}
// Extract the rate and assign it to m_rate_Hz
controller_rate_Hz = cfg.lookup("controller.rate");
controller_rate_Hz = cf->lookup("controller.rate");
Setting& root = cfg.getRoot();
Setting& root = cf->getRoot();
Setting& enabled = root["controller"]["patientData"]["enabled"];
......@@ -105,8 +87,8 @@ 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 = cf->lookup("controller.algorithm.wait_10");
WAIT_5_MIN = cf->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
......
......@@ -2,7 +2,7 @@
// Constructor
MedicalDevice::MedicalDevice() :
MedicalDevice::MedicalDevice() :
m_rate_Hz(50.0), MAX_RATE_Hz(50.0) // Initialize member variables
{
......@@ -18,7 +18,8 @@ void MedicalDevice::update(std::unique_ptr<PhysiologyEngine>& engine) {
// Extract the rate from the configuration file
// str: path to configuration file
// Pure virtual function to be implemented in derived classes
void MedicalDevice::LoadConfig(std::unique_ptr<PhysiologyEngine>&, const char* str){
void
MedicalDevice::LoadConfig(std::unique_ptr<PhysiologyEngine>&, const std::shared_ptr<Config>& cf){
};
......
......@@ -66,26 +66,10 @@ void Monitor::update(std::unique_ptr<PhysiologyEngine>& engine) {
}
void Monitor::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* file_path) {
void Monitor::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::shared_ptr<Config>& cf) {
try
{
// Read configration file
m_cfg.readFile(file_path);
}
catch(const FileIOException &fioex)
{
std::cerr << "I/O error while reading file." << std::endl;
}
catch(const ParseException &pex)
{
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
}
// Grab the monitor rates from config file
m_rate_Hz = m_cfg.lookup("monitor.input_rate");
output_rate_Hz = m_cfg.lookup("monitor.output_rate");
m_rate_Hz = cf->lookup("monitor.input_rate");
output_rate_Hz = cf->lookup("monitor.output_rate");
// Get engine time step/period
time_step = engine->GetTimeStep(TimeUnit::s);
......
......@@ -61,26 +61,13 @@ void Pump::update(std::unique_ptr<PhysiologyEngine>& engine) {
}
void Pump::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* file_path) {
void Pump::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const
std::shared_ptr<Config>& cf) {
try
{
// Read configration file
m_cfg.readFile(file_path);
}
catch(const FileIOException &fioex)
{
std::cerr << "I/O error while reading file." << std::endl;
}
catch(const ParseException &pex)
{
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
}
// Grab pump settings from config file
pump_rate_Hz = m_cfg.lookup("pump.rate");
pump_delay = m_cfg.lookup("pump.delay");
pump_rate_Hz = cf->lookup("pump.rate");
pump_delay = cf->lookup("pump.delay");
// Probably make these global
......
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <map>
#include <libconfig.h++>
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
#include "Pump.h"
#include "Monitor.h"
#include "Controller.h"
......@@ -15,296 +7,258 @@
#include "SimEngine.h"
// 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"
#include "system/physiology/SECardiovascularSystem.h"
#include "system/physiology/SEEnergySystem.h"
#include "system/physiology/SERespiratorySystem.h"
#include "substance/SESubstanceManager.h"
#include "substance/SESubstanceCompound.h"
#include "properties/SEScalar0To1.h"
#include "properties/SEScalarFrequency.h"
#include "properties/SEScalarMass.h"
#include "properties/SEScalarMassPerVolume.h"
#include "properties/SEScalarPressure.h"
#include "properties/SEScalarTemperature.h"
#include "properties/SEScalarTime.h"
#include "properties/SEScalarVolume.h"
#include "properties/SEScalarVolumePerTime.h"
#include "engine/SEEngineTracker.h"
#include "compartment/SECompartmentManager.h"
//--------------------------------------------------------------------------------------------------
/// \brief
/// Usage for applying a Hemorrhage insult to the patient
///
/// \details
/// Refer to the SEHemorrhage class
/// Refer to the SESubstanceManager class
/// Refer to the SESubstanceIVFluids class for applying an IV to the patient
//--------------------------------------------------------------------------------------------------
using namespace libconfig;
int main(int argc, const char * argv[]){
if(argc < 2)
{
cout << "Error: must provide a configuration file\n";
cout << "Usage: ./clasim configfile\n";
}
else
{
clock_t t1, t2, sim_run_time;
vector<string> patients_list;
auto cf = std::make_shared<Config>();
float sim_time_secs, sim_time_mins;
patients_list = get_global_patients(argv[1], cf);
for(auto patient: patients_list) {
// start timer
t1 = clock();
//Simulation input : Name of patient
Simulation(patient);
//stop timer
t2 = clock();
sim_run_time = t2 - t1;
sim_time_secs = ((float)sim_run_time)/CLOCKS_PER_SEC;
sim_time_mins = sim_time_secs/60.0;
cout << "\nThe Simulation for " << patient;
cout << " took "<< sim_time_secs <<" seconds ";
cout <<"or " << sim_time_mins <<" minutes"<<endl;
}
}
}
int main() {
clock_t t1, t2, sim_run_time;
vector<string> patients_list;
auto cf = std::make_shared<Config>();// LibConfig instance
float sim_time_secs, sim_time_mins;
string f_path = clasim_config_dir+"scenario.cfg";
const char* filepath = f_path.c_str();
void Simulation(const string patient_name)
{
try
{
cf->readFile(filepath);
}
// Create the engine and load the patient
std::unique_ptr<PhysiologyEngine> pe = CreatePulseEngine("SimulationEngine_"+patient_name+".log");
pe->GetLogger()->Info("CMD Simulation");
//if (!pe->LoadStateFile("./states/StandardMale@0s.pba"))
if (!pe->LoadStateFile("./states/"+patient_name+"@0s.pba"))
{
pe->GetLogger()->Error("Could not load state, check the error");
return;
}
catch(const FileIOException &fioex) {
std::cerr << "I/O error while reading file: "<< filepath <<std::endl;
}
catch(const ParseException &pex) {
std::cerr << "Parse error at " << pex.getFile() << ":"<< pex.getLine()
<< " - " << pex.getError() << std::endl;
}
// Create data requests for each value that should be written to the output log as the engine is executing
// Physiology System Names are defined on the System Objects
// defined in the Physiology.xsd file
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("HeartRate", FrequencyUnit::Per_min);
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("BloodVolume", VolumeUnit::mL);
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("MeanArterialPressure", PressureUnit::mmHg);
pe->GetEngineTracker()->GetDataRequestManager().SetResultsFilename("PulseSimEngine_"+patient_name+".txt");
patients_list = get_global_patients(cf);
//instatiate Hemorrhage Action
SEHemorrhage hemorrhageLeg;
const double initialMAP = 70.0;
double currentMAP;
for(auto patient: patients_list) {
// start timer
t1 = clock();
// Configuration file path
// Note: Path is relative to the bin folder not src folder
const char* fname = "./config/simulation_scenario.cfg";
// Simulation input : Name of patient, Config object
Simulation(patient, cf);
// Configuration object
auto cfg = std::make_shared<Config>();
// stop timer
t2 = clock();
//instatiate enviroment object
CMD::Environment sim_env;
PhysiologyData data;
sim_run_time = t2 - t1;
sim_time_secs = ((double)sim_run_time)/CLOCKS_PER_SEC;
sim_time_mins = sim_time_secs/60.0;
// load simulation environment
Global_LoadConfig(pe, cfg, fname, &sim_env);
cout << "\nThe Simulation for " << patient;
cout << " took "<< sim_time_secs <<" seconds ";
cout <<"or " << sim_time_mins <<" minutes"<<endl;
}
// List of pumps
map<string, Pump*> pumps;
//Iintialize Pump
Pump pump_saline(&sim_env, &data, "Saline");
pump_saline.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));
void Simulation(const string patient_name, const std::shared_ptr<Config>& cf) {
//Initialize Controller
Controller controller(&sim_env, &data, pumps);
controller.LoadConfig(pe, fname);
// Create the engine and load the patient
std::unique_ptr<PhysiologyEngine> pe = CreatePulseEngine(clasim_results_dir+
"SimulationEngine_"+patient_name+".log");
pe->GetLogger()->Info("CLA Simulation");
//Initialize Monitor
Monitor monitor(&sim_env, &data);
// Call this member function before 'update member function'
// to load new rate value from the config file
monitor.LoadConfig(pe, fname);
if (!pe->LoadStateFile(pulse_state_dir+patient_name+"@0s.pba"))
{
pe->GetLogger()->Error("Could not load state, check the error");
return;
}
// Create data requests for each value that should be written to the output log as
// the engine is executing
// Physiology System Names are defined on the System Objects
// defined in the Physiology.xsd file
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest(
"HeartRate", FrequencyUnit::Per_min);
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest(
"BloodVolume", VolumeUnit::mL);
pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest(
"MeanArterialPressure", PressureUnit::mmHg);
// Store requested data in a file
pe->GetEngineTracker()->GetDataRequestManager().SetResultsFilename(
clasim_results_dir+"PulseSimEngine_"+patient_name+".txt");
//logger
sim_env.logger = std::make_shared<SimulationLogger>("SimulationEngineLog_"+patient_name+".txt");
// Hemorrhage Action
SEHemorrhage hemorrhageLeg;
const double initialMAP = 70.0;
double currentMAP;
double hemorrhageRate;
bool STOP = false; // Execute stop hemmorrhage only once; without this it be executed for each timestep
bool DEVICES_START = false;
// Enviroment object
CMD::Environment sim_env;
PhysiologyData data;
// stop when the set time is reached
while (sim_env.time_index <= sim_env.simulation_timesteps) {
// Load simulation environment/variables
Global_LoadConfig(pe, cf, &sim_env);
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
// Hash map for the different pumps
map<string, Pump*> pumps;
cout << "\nHemorrhage Started at: " << pe->GetSimulationTime(TimeUnit::s) << endl;
// Intialize Saline Pump
Pump pump_saline(&sim_env, &data, "Saline");
pump_saline.LoadConfig(pe, cf);
//the location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
//the rate of hemorrhage
hemorrhageLeg.GetRate().SetValue(150,VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
// Initialize Norepinephrine Pump
Pump pump_bpdrug(&sim_env, &data, "Norepinephrine");
pump_bpdrug.LoadConfig(pe, cf);
STOP = true;
}
pumps.insert(make_pair("saline", &pump_saline));
pumps.insert(make_pair("bpdrug", &pump_bpdrug));
currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
// Initialize Controller
Controller controller(&sim_env, &data, pumps);
controller.LoadConfig(pe, cf);
if( currentMAP <= initialMAP && STOP){
// Initialize Monitor
Monitor monitor(&sim_env, &data);
monitor.LoadConfig(pe, cf);
cout << "\nHemorrhage Stoppd at: " << pe->GetSimulationTime(TimeUnit::s) << endl;
// logger
sim_env.logger = std::make_shared<SimulationLogger>(clasim_results_dir+
"SimulationEngineLog_"+patient_name+".txt");
//the location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
// Stop hemorrhage
hemorrhageLeg.GetRate().SetValue(0,VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
// Execute stop hemmorrhage only once; without this it'd be executed for each
// timestep
bool STOP = false;
bool DEVICES_START = false;
STOP = false;
// Stop when the set time is reached
while (sim_env.time_index <= sim_env.simulation_timesteps) {
// instruct devices to start
DEVICES_START = true;
cout << "START DEVICES" << endl;
}
sim_env.sim_currentTime = pe->GetSimulationTime(TimeUnit::s);
if (DEVICES_START) {
// event_hemorrage_start
if(sim_env.time_index == sim_env.simulation_injury_start_timestep) {
monitor.update(pe);
controller.update(pe);
pumps["saline"]->update(pe);
pumps["bpdrug"]->update(pe);
// Hemorrhage Starts
hemorrhageRate = 250;
cout << "\nHemorrhage Started at: "<<pe->GetSimulationTime(TimeUnit::s)<<
endl;
}
// location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
// rate of hemorrhage
hemorrhageLeg.GetRate().SetValue(hemorrhageRate,
VolumePerTimeUnit::mL_Per_min);
// Engine processes this action
pe->ProcessAction(hemorrhageLeg);
/*
if( sim_env.time_index == sim_env.simulation_injury_stop_timestep ){
STOP = true;
}
cout << "\nHemorrhage Stoppd at: " << pe->GetSimulationTime(TimeUnit::s) << endl;
// polling MAP
currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(
PressureUnit::mmHg);
//the location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
// Stop hemorrhage
hemorrhageLeg.GetRate().SetValue(0,VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
}
*/
// track patient data
pe->GetEngineTracker()->TrackData(pe->GetSimulationTime(TimeUnit::s));
// Advance engine for each time step
pe->AdvanceModelTime();
if(currentMAP <= initialMAP && STOP) {
// increment environment time index whenever engine advances
sim_env.time_index++;
// Hemorrhage Stops
hemorrhageRate = 0;
cout<<"\nHemorrhage Stoppd at: "<< pe->GetSimulationTime(TimeUnit::s)<<
endl;
}// End while looop
// location of the hemorrhage
hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
hemorrhageLeg.GetRate().SetValue(hemorrhageRate,
VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
}// End Simulation function
STOP = false;
// instruct devices to start
DEVICES_START = true;
void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::shared_ptr<Config>& cf, const char* file_path, CMD::Environment* env) {
cout << "START DEVICES" << endl;
}
try
{
cf->readFile(file_path); // Read configration file
}
catch(const FileIOException &fioex)
{
std::cerr << "I/O error while reading file." << std::endl;
}
catch(const ParseException &pex)
{
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
}
if (DEVICES_START) {
env->simulation_time = cf->lookup("simulation.time.run");
env->simulation_injury_start = cf->lookup("simulation.time.injury_start");
env->simulation_injury_stop = cf->lookup("simulation.time.injury_stop");
monitor.update(pe);
controller.update(pe);
pumps["saline"]->update(pe);
pumps["bpdrug"]->update(pe);
env->time_index = 0; // initialize the time index
env->engine_timestep = engine->GetTimeStep(TimeUnit::s);
env->simulation_timesteps = env->simulation_time / env->engine_timestep;
env->simulation_injury_start_timestep = env->simulation_injury_start / env->engine_timestep;
env->simulation_injury_stop_timestep = env->simulation_injury_stop / env->engine_timestep;
env->vector_index = 0;
}
env->sim_currentTime = engine->GetSimulationTime(TimeUnit::s);
// Track patient data
pe->GetEngineTracker()->TrackData(pe->GetSimulationTime(TimeUnit::s));
// Advance engine for each time step
pe->AdvanceModelTime();
// increment environment time index whenever engine advances
sim_env.time_index++;
//env->logger = std::make_shared<SimulationLogger>("SimulatoinEngineLog.txt");
}// End while loop
}// End Global_LoadConfig
vector<string> get_global_patients(const char* filepath,const std::shared_ptr<Config>& cf){
}// End Simulation function
vector<string> patients;
try
{
cf->readFile(filepath);
}
void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::shared_ptr<Config>& cf, CMD::Environment* env) {
/* get the simulation run time */
try
{
env->simulation_time = cf->lookup("simulation.time.run");
}
catch(const SettingNotFoundException) {
cout << "Setting Not Found: simulation.time.run" << endl;
}
/* get the injury start time */
try
{
env->simulation_injury_start = cf->lookup("simulation.time.injury_start");
}
catch(const SettingNotFoundException) {
cout << "Setting Not Found: simulation.time.injury_start" << endl;
}
/* get the injury stop time */
try
{
env->simulation_injury_stop = cf->lookup("simulation.time.injury_stop");
}
catch(const SettingNotFoundException) {
cout << "Setting Not Found: simulation.time.injury_stop" << endl;
}
env->time_index = 0; // initialize the time index
env->engine_timestep = engine->GetTimeStep(TimeUnit::s);
env->simulation_timesteps = env->simulation_time / env->engine_timestep;
env->simulation_injury_start_timestep = env->simulation_injury_start /
env->engine_timestep;
env->simulation_injury_stop_timestep = env->simulation_injury_stop /
env->engine_timestep;
env->vector_index = 0;
env->sim_currentTime = engine->GetSimulationTime(TimeUnit::s);
catch(const FileIOException &fioex) {
std::cerr << "I/O error while reading file." << std::endl;
//return(EXIT_FAILURE);
}
catch(const ParseException &pex) {
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
//return(EXIT_FAILURE);
}
}// End Global_LoadConfig
try{
vector<string> get_global_patients(const std::shared_ptr<Config>& cf) {